cosmetics
[tomato.git] / release / src / router / httpd / devlist.c
blob3a8656c6a7b4c4655ecb744cddbc59050e25d344
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
8 #include "tomato.h"
10 #include <ctype.h>
11 #include <sys/ioctl.h>
12 #include <net/if.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
16 #include <wlutils.h>
19 void asp_arplist(int argc, char **argv)
21 FILE *f;
22 char s[512];
23 char ip[16];
24 char mac[18];
25 char dev[17];
26 char comma;
27 unsigned int flags;
30 cat /proc/net/arp
31 IP address HW type Flags HW address Mask Device
32 192.168.0.1 0x1 0x2 00:01:02:03:04:05 * vlan1
35 web_puts("\narplist = [");
36 comma = ' ';
37 if ((f = fopen("/proc/net/arp", "r")) != NULL) {
38 while (fgets(s, sizeof(s), f)) {
39 if (sscanf(s, "%15s %*s 0x%X %17s %*s %16s", ip, &flags, mac, dev) != 4) continue;
40 if ((strlen(mac) != 17) || (strcmp(mac, "00:00:00:00:00:00") == 0)) continue;
41 if (flags == 0) continue;
42 // if ((nvram_match("wan_ifname", dev)) && (!nvram_match("wan_ipaddr", ip))) continue; // half
43 web_printf("%c['%s','%s','%s']", comma, ip, mac, dev);
44 comma = ',';
46 fclose(f);
48 web_puts("];\n");
51 // checkme: any easier way to do this? zzz
52 static int get_wds_ifname(const struct ether_addr *ea, char *ifname)
54 struct ifreq ifr;
55 int sd;
56 int i;
57 struct ether_addr e;
59 if ((sd = socket(PF_INET, SOCK_DGRAM, 0)) >= 0) {
60 // wds doesn't show up under SIOCGIFCONF; seems to start at 17 (?)
61 for (i = 1; i < 32; ++i) {
62 ifr.ifr_ifindex = i;
63 if ((ioctl(sd, SIOCGIFNAME, &ifr) == 0) &&
64 (strncmp(ifr.ifr_name, "wds", 3) == 0) &&
65 (wl_ioctl(ifr.ifr_name, WLC_WDS_GET_REMOTE_HWADDR, &e.octet, sizeof(e.octet)) == 0)) {
66 if (memcmp(ea->octet, e.octet, sizeof(e.octet)) == 0) {
67 close(sd);
68 strlcpy(ifname, ifr.ifr_name, 16);
69 return 1;
73 close(sd);
75 return 0;
78 static int get_wl_clients(int idx, int unit, int subunit, void *param)
80 char *comma = param;
81 int i;
82 char *p;
83 char buf[32];
84 #if 1
85 char *wlif;
86 scb_val_t rssi;
87 sta_info_t sti;
88 int cmd;
89 struct maclist *mlist;
90 int mlsize;
91 char ifname[16];
93 mlsize = sizeof(struct maclist) + (255 * sizeof(struct ether_addr));
94 if ((mlist = malloc(mlsize)) != NULL) {
95 wlif = nvram_safe_get(wl_nvname("ifname", unit, 0));
96 cmd = WLC_GET_ASSOCLIST;
97 while (1) {
98 mlist->count = 255;
99 if (wl_ioctl(wlif, cmd, mlist, mlsize) == 0) {
100 for (i = 0; i < mlist->count; ++i) {
101 rssi.ea = mlist->ea[i];
102 rssi.val = 0;
103 if (wl_ioctl(wlif, WLC_GET_RSSI, &rssi, sizeof(rssi)) != 0) continue;
105 // sta_info0<mac>
106 memset(&sti, 0, sizeof(sti));
107 strcpy((char *)&sti, "sta_info");
108 memcpy((char *)&sti + 9, rssi.ea.octet, 6);
109 if (wl_ioctl(wlif, WLC_GET_VAR, &sti, sizeof(sti)) != 0) continue;
111 p = wlif;
112 if (sti.flags & WL_STA_WDS) {
113 if (cmd != WLC_GET_WDSLIST) continue;
114 if ((sti.flags & WL_WDS_LINKUP) == 0) continue;
115 if (get_wds_ifname(&rssi.ea, ifname)) p = ifname;
118 web_printf("%c['%s','%s',%d,%u,%u,%u,%d]",
119 *comma,
121 ether_etoa(rssi.ea.octet, buf),
122 rssi.val,
123 sti.tx_rate, sti.rx_rate, sti.in, unit);
124 *comma = ',';
127 if (cmd == WLC_GET_WDSLIST) break;
128 cmd = WLC_GET_WDSLIST;
130 free(mlist);
132 #else
133 char *wlif;
134 scb_val_t rssi;
135 sta_info_t sti;
136 int j;
137 struct maclist *mlist;
138 int mlsize;
139 char ifname[16];
141 mlsize = sizeof(struct maclist) + (127 * sizeof(struct ether_addr));
142 if ((mlist = malloc(mlsize)) != NULL) {
143 for (j = 0; j < 2; ++j) {
144 wlif = nvram_safe_get("wl0_ifname");
145 strcpy((char *)mlist, j ? "autho_sta_list" : "authe_sta_list");
146 if (wl_ioctl(wlif, WLC_GET_VAR, mlist, mlsize) == 0) {
147 for (i = 0; i < mlist->count; ++i) {
148 rssi.ea = mlist->ea[i];
149 rssi.val = 0;
150 if (wl_ioctl(wlif, WLC_GET_RSSI, &rssi, sizeof(rssi)) != 0) continue;
152 // sta_info0<mac>
153 memset(&sti, 0, sizeof(sti));
154 strcpy((char *)&sti, "sta_info");
155 memcpy((char *)&sti + 9, rssi.ea.octet, 6);
156 if (wl_ioctl(wlif, WLC_GET_VAR, &sti, sizeof(sti)) != 0) continue;
158 p = wlif;
159 if (sti.flags & WL_STA_WDS) {
160 if ((sti.flags & WL_WDS_LINKUP) == 0) continue;
161 if (get_wds_ifname(&rssi.ea, ifname)) p = ifname;
164 web_printf("%c['%s','%s',%d]",
165 *comma,
167 ether_etoa(rssi.ea.octet, buf),
168 rssi.val);
169 *comma = ',';
173 free(mlist);
175 #endif
177 return 0;
180 void asp_devlist(int argc, char **argv)
182 char *p;
183 FILE *f;
184 char buf[1024];
185 char comma;
187 // must be here for easier call via update.cgi. arg is ignored
188 asp_arplist(0, NULL);
189 asp_wlnoise(0, NULL);
193 p = js_string(nvram_safe_get("dhcpd_static"));
194 web_printf("dhcpd_static = '%s'.split('>');\n", p ? p : "");
195 free(p);
199 web_puts("wldev = [");
200 comma = ' ';
201 foreach_wif(1, &comma, get_wl_clients);
202 web_puts("];\n");
206 unsigned long expires;
207 char mac[32];
208 char ip[32];
209 char hostname[256];
210 char *host;
212 web_puts("dhcpd_lease = [");
213 if (nvram_match("lan_proto", "dhcp")) {
214 f_write("/var/tmp/dhcp/leases.!", NULL, 0, 0, 0666);
216 // dump the leases to a file
217 if (killall("dnsmasq", SIGUSR2) == 0) {
218 // helper in dnsmasq will remove this when it's done
219 f_wait_notexists("/var/tmp/dhcp/leases.!", 5);
222 if ((f = fopen("/var/tmp/dhcp/leases", "r")) != NULL) {
223 comma = ' ';
224 while (fgets(buf, sizeof(buf), f)) {
225 if (sscanf(buf, "%lu %17s %15s %255s", &expires, mac, ip, hostname) != 4) continue;
226 host = js_string((hostname[0] == '*') ? "" : hostname);
227 web_printf("%c['%s','%s','%s','%s']", comma,
228 (host ? host : ""), ip, mac, ((expires == 0) ? "non-expiring" : reltime(buf, expires)));
229 free(host);
230 comma = ',';
232 fclose(f);
234 unlink("/var/tmp/dhcp/leases");
236 web_puts("];");