Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / rc / wnas.c
blob6e2c3bed8a7c990749e6b42efebc6242ebb3f014
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
31 #include "rc.h"
33 #include <sys/sysinfo.h>
34 #include <sys/ioctl.h>
35 #include <bcmutils.h>
36 #include <wlutils.h>
39 // ref: http://wiki.openwrt.org/OpenWrtDocs/nas
41 // #define DEBUG_TIMING
43 void notify_nas(const char *ifname);
45 static int security_on(int idx, int unit, int subunit, void *param)
47 return nvram_get_int(wl_nvname("radio", unit, 0)) && (!nvram_match(wl_nvname("security_mode", unit, subunit), "disabled"));
50 static int is_wds(int idx, int unit, int subunit, void *param)
52 return nvram_get_int(wl_nvname("radio", unit, 0)) && nvram_get_int(wl_nvname("wds_enable", unit, subunit));
55 #ifndef CONFIG_BCMWL5
56 static int is_sta(int idx, int unit, int subunit, void *param)
58 return nvram_match(wl_nvname("mode", unit, subunit), "sta");
60 #endif
62 int wds_enable(void)
64 return foreach_wif(1, NULL, is_wds);
67 #ifdef TCONFIG_VLAN
68 int wl_security_on(void) {
69 return foreach_wif(1, NULL, security_on);
72 static int nas_starter(int idx, int unit, int subunit, void *param) {
73 char unit_str[] = "000000";
74 char lanN_ifname[] = "lanXX_ifname";
75 char lanN_ifnames[] = "lanXX_ifnames";
76 char br;
77 if(nvram_get_int(wl_nvname("bss_enabled", unit, subunit))) {
78 if (nvram_match(wl_nvname("mode", unit, subunit), "ap")) {
79 if (subunit > 0)
80 snprintf(unit_str, sizeof(unit_str), "%d.%d", unit, subunit);
81 else
82 snprintf(unit_str, sizeof(unit_str), "%d", unit);
84 for(br=3 ; br>=0 ; br--) {
85 char bridge[2] = "0";
86 if (br!=0)
87 bridge[0]+=br;
88 else
89 strcpy(bridge, "");
91 snprintf(lanN_ifname, sizeof(lanN_ifname), "lan%s_ifname", bridge);
92 snprintf(lanN_ifnames, sizeof(lanN_ifnames), "lan%s_ifnames", bridge);
94 if(strstr(nvram_safe_get(lanN_ifnames),nvram_safe_get(wl_nvname("ifname", unit, subunit))) != NULL) {
95 xstart("/usr/sbin/nas.sh", unit_str, nvram_safe_get(lanN_ifname));
96 sleep(3);
100 if(is_sta(idx, unit, subunit, NULL)) {
101 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
102 sleep(1);
105 return 0;
107 #endif /* TCONFIG_VLAN */
109 void start_nas(void)
111 if (!foreach_wif(1, NULL, security_on)) {
112 return;
115 #ifdef DEBUG_TIMING
116 struct sysinfo si;
117 sysinfo(&si);
118 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
119 #else
120 _dprintf("%s\n", __FUNCTION__);
121 #endif
123 #ifdef CONFIG_BCMWL5
124 setenv("UDP_BIND_IP", "127.0.0.1", 1);
125 eval("eapd");
126 unsetenv("UDP_BIND_IP");
127 eval("nas");
128 #else
129 mode_t m;
131 m = umask(0077);
133 #ifdef TCONFIG_VLAN
134 if(nvram_get_int("nas_alternate")) {
135 foreach_wif(1, NULL, nas_starter);
136 } else {
137 if(strstr(nvram_safe_get("lan_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
138 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan");
139 if(strstr(nvram_safe_get("lan1_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
140 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan1");
141 if(strstr(nvram_safe_get("lan2_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
142 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan2");
143 if(strstr(nvram_safe_get("lan3_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
144 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan3");
146 if (foreach_wif(1, NULL, is_sta))
147 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
149 #else /* TCONFIG_VLAN */
150 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan");
151 if (foreach_wif(1, NULL, is_sta))
152 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
153 #endif /* TCONFIG_VLAN */
154 umask(m);
155 #endif /* CONFIG_BCMWL5 */
157 if (wds_enable()) {
158 // notify NAS of all wds up ifaces upon startup
159 FILE *fd;
160 char *ifname, buf[256];
162 if ((fd = fopen("/proc/net/dev", "r")) != NULL) {
163 fgets(buf, sizeof(buf) - 1, fd); // header lines
164 fgets(buf, sizeof(buf) - 1, fd);
165 while (fgets(buf, sizeof(buf) - 1, fd)) {
166 if ((ifname = strchr(buf, ':')) == NULL) continue;
167 *ifname = 0;
168 if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
169 else ++ifname;
170 if (strstr(ifname, "wds")) {
171 notify_nas(ifname);
174 fclose(fd);
179 void stop_nas(void)
181 #ifdef DEBUG_TIMING
182 struct sysinfo si;
183 sysinfo(&si);
184 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
185 #else
186 _dprintf("%s\n", __FUNCTION__);
187 #endif
189 killall_tk("nas");
190 #ifdef CONFIG_BCMWL5
191 killall_tk("eapd");
192 #endif /* CONFIG_BCMWL5 */
195 void notify_nas(const char *ifname)
197 #ifdef DEBUG_TIMING
198 struct sysinfo si;
199 sysinfo(&si);
200 _dprintf("%s: ifname=%s uptime=%ld\n", __FUNCTION__, ifname, si.uptime);
201 #else
202 _dprintf("%s: ifname=%s\n", __FUNCTION__, ifname);
203 #endif
205 #ifdef CONFIG_BCMWL5
207 /* Inform driver to send up new WDS link event */
208 if (wl_iovar_setint((char *)ifname, "wds_enable", 1)) {
209 _dprintf("%s: set wds_enable failed\n", ifname);
212 #else /* !CONFIG_BCMWL5 */
214 if (!foreach_wif(1, NULL, security_on)) return;
216 int i;
217 int unit;
219 i = 10;
220 while (pidof("nas") == -1) {
221 _dprintf("waiting for nas i=%d\n", i);
222 if (--i < 0) {
223 syslog(LOG_ERR, "Unable to find nas");
224 break;
226 sleep(1);
228 sleep(5);
230 /* the wireless interface must be configured to run NAS */
231 wl_ioctl((char *)ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
233 xstart("nas4not", "lan", ifname, "up", "auto",
234 nvram_safe_get(wl_nvname("crypto", unit, 0)), // aes, tkip (aes+tkip ok?)
235 nvram_safe_get(wl_nvname("akm", unit, 0)), // psk (only?)
236 nvram_safe_get(wl_nvname("wpa_psk", unit, 0)), // shared key
237 nvram_safe_get(wl_nvname("ssid", unit, 0)) // ssid
240 #endif /* CONFIG_BCMWL5 */
246 #if 0 // old stuff for ref
250 void del_wds_wsec(int unit, int which)
252 char name[32];
254 sprintf(name, "wl%d_wds%d", unit, which);
255 nvram_unset(name);
261 xstart("nas",
262 nvram_match("wl_mode", "sta") ? "-S" : "-A",
263 "-H", "34954",
264 "-i", nvram_safe_get("wl_ifname"),
265 "-l", nvram_safe_get("lan_ifname"),
270 // WPA doesn't support shared key removed, handled during config set zzz
271 // if (strstr(nvram_safe_get("wl_akm"), "wpa") != NULL) {
272 // nvram_set("wl_auth", "0");
273 // }
275 // if ((nvram_match("wl_mode", "sta")) && (nvram_match("wl_akm", "psk psk2"))) {
276 // nvram_set("wl_akm", "psk2");
277 // }
279 // convert_wds();
284 static int get_wds_wsec(int unit, int which, char *mac, char *role, char *crypto, char *auth, char *ssid, char *pass)
286 char buf[512];
287 char *next;
289 sprintf(buf, "wl%d_wds%d", unit, which);
290 strlcpy(buf, nvram_safe_get(buf), sizeof(buf));
291 next = buf;
293 strcpy(mac, strsep(&next, ","));
294 if (!next) return 0;
296 strcpy(role, strsep(&next, ","));
297 if (!next) return 0;
299 strcpy(crypto, strsep(&next, ","));
300 if (!next) return 0;
302 strcpy(auth, strsep(&next, ","));
303 if (!next) return 0;
305 strcpy(ssid, strsep(&next, ","));
306 if (!next) return 0;
308 strcpy(pass, next);
309 return 1;
312 static void convert_wds(void)
314 char wds_mac[254];
315 char buf[254];
317 if (nvram_match("wl_wds", "")) { // For Router, accept all WDS link
318 strcpy(wds_mac, "*");
320 else { // For AP, assign remote WDS MAC
321 strlcpy(wds_mac, nvram_safe_get("wl_wds"), sizeof(wds_mac));
325 // For WPA-PSK mode, we want to convert wl_wds_mac to wl0_wds0 ... wl0_wds255
326 if (strstr(nvram_safe_get("wl_akm"), "psk")) {
327 char wl_wds[32];
328 int i = 0;
329 int j;
330 char mac[254];
331 char *next;
333 foreach(mac, wds_mac, next) {
334 snprintf(wl_wds, sizeof(wl_wds), "wl0_wds%d", i);
335 snprintf(buf, sizeof(buf), "%s,auto,%s,%s,%s,%s",
336 mac,
337 nvram_safe_get("wl_crypto"),
338 nvram_safe_get("wl_akm"),
339 nvram_safe_get("wl_ssid"),
340 nvram_safe_get("wl_wpa_psk"));
342 nvram_set(wl_wds, buf);
343 i++;
346 for (j = i; j < 20; j++)
347 del_wds_wsec(0, j);
352 #if 0
353 void notify_nas(char *ifname)
355 char *argv[] = {"nas4not", "lan", ifname, "up",
356 NULL, /* role */
357 NULL, /* crypto */
358 NULL, /* auth */
359 NULL, /* passphrase */
360 NULL, /* ssid */
361 NULL};
362 char tmp[100], prefix[32];
363 int unit;
364 char remote[ETHER_ADDR_LEN];
365 char ssid[48], pass[80], auth[16], crypto[16], role[8];
366 int i;
368 /* the wireless interface must be configured to run NAS */
369 wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
370 sprintf(prefix, "wl%d_", unit);
371 if (nvram_match(strcat_r(prefix, "akm", tmp), "") && nvram_match(strcat_r(prefix, "auth_mode", tmp), "none")) {
372 return;
375 // wait until nas is up and running
376 char s[64];
377 int r;
379 r = 10;
380 while (f_read("/tmp/nas.lan.pid", s, sizeof(s)) <= 0) {
381 if (--r <= 0) {
382 cprintf("notify_nas: unable to find nas");
383 break;
385 sleep(1);
387 sleep(3);
390 /* find WDS link configuration */
391 wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
392 for (i = 0; i < 20; ++i) {
393 char mac[ETHER_ADDR_STR_LEN];
394 uint8 ea[ETHER_ADDR_LEN];
396 if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
397 ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
398 argv[4] = role;
399 argv[5] = crypto;
400 argv[6] = auth;
401 argv[7] = pass;
402 argv[8] = ssid;
404 cprintf("notify_nas: get_wds_wsec(%d,%d) crypto=%s", unit, i, argv[5]);
405 break;
408 /* did not find WDS link configuration, use wireless' */
409 if (i == 20) {
410 /* role */
411 argv[4] = "auto";
412 /* crypto */
413 argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
414 /* auth mode */
415 argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
416 /* passphrase */
417 argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
418 /* ssid */
419 argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
421 cprintf("notify_nas: i==MAX crypto=%s", argv[5]);
424 #if 0
425 char cl[512];
426 cl[0] = 0;
427 for (i = 0; argv[i]; ++i) {
428 strcat(cl, argv[i]);
429 strcat(cl, " ");
431 cprintf("notify_nas: %s", cl);
432 #endif
434 int pid;
435 _eval(argv, ">/dev/console", 0, &pid);
437 #endif
441 #endif // 0