Merge branch 'VLAN-MultiSSID' into Toastman-VLAN-MultiSSID
[tomato.git] / release / src / router / rc / wnas.c
blob2fdd6c9bfdda10c5c5135e330bf424d9641d7a7c
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 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 if(nvram_get_int(wl_nvname("bss_enabled", unit, subunit))) {
75 if (nvram_match(wl_nvname("mode", unit, subunit), "ap")) {
76 if (subunit > 0)
77 snprintf(unit_str, sizeof(unit_str), "%d.%d", unit, subunit);
78 else
79 snprintf(unit_str, sizeof(unit_str), "%d", unit);
81 if(strstr(nvram_safe_get("lan_ifnames"),nvram_safe_get(wl_nvname("ifname", unit, subunit))) != NULL)
82 xstart("/usr/sbin/nas.sh", unit_str, nvram_safe_get("lan_ifname"));
83 if(strstr(nvram_safe_get("lan1_ifnames"),nvram_safe_get(wl_nvname("ifname", unit, subunit))) != NULL)
84 xstart("/usr/sbin/nas.sh", unit_str, nvram_safe_get("lan1_ifname"));
85 if(strstr(nvram_safe_get("lan2_ifnames"),nvram_safe_get(wl_nvname("ifname", unit, subunit))) != NULL)
86 xstart("/usr/sbin/nas.sh", unit_str, nvram_safe_get("lan2_ifname"));
87 if(strstr(nvram_safe_get("lan3_ifnames"),nvram_safe_get(wl_nvname("ifname", unit, subunit))) != NULL)
88 xstart("/usr/sbin/nas.sh", unit_str, nvram_safe_get("lan3_ifname"));
91 return 0;
94 void start_nas(void)
96 if (!foreach_wif(1, NULL, security_on)) {
97 return;
100 #ifdef DEBUG_TIMING
101 struct sysinfo si;
102 sysinfo(&si);
103 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
104 #else
105 _dprintf("%s\n", __FUNCTION__);
106 #endif
108 #ifdef CONFIG_BCMWL5
109 setenv("UDP_BIND_IP", "127.0.0.1", 1);
110 eval("eapd");
111 unsetenv("UDP_BIND_IP");
112 eval("nas");
113 #else
114 mode_t m;
116 m = umask(0077);
117 if(nvram_get_int("nas_alternate")) {
118 foreach_wif(1, NULL, nas_starter);
119 } else {
120 if(strstr(nvram_safe_get("lan_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
121 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan");
122 if(strstr(nvram_safe_get("lan1_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
123 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan1");
124 if(strstr(nvram_safe_get("lan2_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
125 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan2");
126 if(strstr(nvram_safe_get("lan3_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
127 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan3");
130 if (foreach_wif(1, NULL, is_sta))
131 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
132 umask(m);
133 #endif /* CONFIG_BCMWL5 */
135 if (wds_enable()) {
136 // notify NAS of all wds up ifaces upon startup
137 FILE *fd;
138 char *ifname, buf[256];
140 if ((fd = fopen("/proc/net/dev", "r")) != NULL) {
141 fgets(buf, sizeof(buf) - 1, fd); // header lines
142 fgets(buf, sizeof(buf) - 1, fd);
143 while (fgets(buf, sizeof(buf) - 1, fd)) {
144 if ((ifname = strchr(buf, ':')) == NULL) continue;
145 *ifname = 0;
146 if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
147 else ++ifname;
148 if (strstr(ifname, "wds")) {
149 notify_nas(ifname);
152 fclose(fd);
157 void stop_nas(void)
159 #ifdef DEBUG_TIMING
160 struct sysinfo si;
161 sysinfo(&si);
162 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
163 #else
164 _dprintf("%s\n", __FUNCTION__);
165 #endif
167 killall_tk("nas");
168 #ifdef CONFIG_BCMWL5
169 killall_tk("eapd");
170 #endif /* CONFIG_BCMWL5 */
173 void notify_nas(const char *ifname)
175 #ifdef DEBUG_TIMING
176 struct sysinfo si;
177 sysinfo(&si);
178 _dprintf("%s: ifname=%s uptime=%ld\n", __FUNCTION__, ifname, si.uptime);
179 #else
180 _dprintf("%s: ifname=%s\n", __FUNCTION__, ifname);
181 #endif
183 #ifdef CONFIG_BCMWL5
185 /* Inform driver to send up new WDS link event */
186 if (wl_iovar_setint((char *)ifname, "wds_enable", 1)) {
187 _dprintf("%s: set wds_enable failed\n", ifname);
190 #else /* !CONFIG_BCMWL5 */
192 if (!foreach_wif(1, NULL, security_on)) return;
194 int i;
195 int unit;
197 i = 10;
198 while (pidof("nas") == -1) {
199 _dprintf("waiting for nas i=%d\n", i);
200 if (--i < 0) {
201 syslog(LOG_ERR, "Unable to find nas");
202 break;
204 sleep(1);
206 sleep(5);
208 /* the wireless interface must be configured to run NAS */
209 wl_ioctl((char *)ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
211 xstart("nas4not", "lan", ifname, "up", "auto",
212 nvram_safe_get(wl_nvname("crypto", unit, 0)), // aes, tkip (aes+tkip ok?)
213 nvram_safe_get(wl_nvname("akm", unit, 0)), // psk (only?)
214 nvram_safe_get(wl_nvname("wpa_psk", unit, 0)), // shared key
215 nvram_safe_get(wl_nvname("ssid", unit, 0)) // ssid
218 #endif /* CONFIG_BCMWL5 */
224 #if 0 // old stuff for ref
228 void del_wds_wsec(int unit, int which)
230 char name[32];
232 sprintf(name, "wl%d_wds%d", unit, which);
233 nvram_unset(name);
239 xstart("nas",
240 nvram_match("wl_mode", "sta") ? "-S" : "-A",
241 "-H", "34954",
242 "-i", nvram_safe_get("wl_ifname"),
243 "-l", nvram_safe_get("lan_ifname"),
248 // WPA doesn't support shared key removed, handled during config set zzz
249 // if (strstr(nvram_safe_get("wl_akm"), "wpa") != NULL) {
250 // nvram_set("wl_auth", "0");
251 // }
253 // if ((nvram_match("wl_mode", "sta")) && (nvram_match("wl_akm", "psk psk2"))) {
254 // nvram_set("wl_akm", "psk2");
255 // }
257 // convert_wds();
262 static int get_wds_wsec(int unit, int which, char *mac, char *role, char *crypto, char *auth, char *ssid, char *pass)
264 char buf[512];
265 char *next;
267 sprintf(buf, "wl%d_wds%d", unit, which);
268 strlcpy(buf, nvram_safe_get(buf), sizeof(buf));
269 next = buf;
271 strcpy(mac, strsep(&next, ","));
272 if (!next) return 0;
274 strcpy(role, strsep(&next, ","));
275 if (!next) return 0;
277 strcpy(crypto, strsep(&next, ","));
278 if (!next) return 0;
280 strcpy(auth, strsep(&next, ","));
281 if (!next) return 0;
283 strcpy(ssid, strsep(&next, ","));
284 if (!next) return 0;
286 strcpy(pass, next);
287 return 1;
290 static void convert_wds(void)
292 char wds_mac[254];
293 char buf[254];
295 if (nvram_match("wl_wds", "")) { // For Router, accept all WDS link
296 strcpy(wds_mac, "*");
298 else { // For AP, assign remote WDS MAC
299 strlcpy(wds_mac, nvram_safe_get("wl_wds"), sizeof(wds_mac));
303 // For WPA-PSK mode, we want to convert wl_wds_mac to wl0_wds0 ... wl0_wds255
304 if (strstr(nvram_safe_get("wl_akm"), "psk")) {
305 char wl_wds[32];
306 int i = 0;
307 int j;
308 char mac[254];
309 char *next;
311 foreach(mac, wds_mac, next) {
312 snprintf(wl_wds, sizeof(wl_wds), "wl0_wds%d", i);
313 snprintf(buf, sizeof(buf), "%s,auto,%s,%s,%s,%s",
314 mac,
315 nvram_safe_get("wl_crypto"),
316 nvram_safe_get("wl_akm"),
317 nvram_safe_get("wl_ssid"),
318 nvram_safe_get("wl_wpa_psk"));
320 nvram_set(wl_wds, buf);
321 i++;
324 for (j = i; j < 20; j++)
325 del_wds_wsec(0, j);
330 #if 0
331 void notify_nas(char *ifname)
333 char *argv[] = {"nas4not", "lan", ifname, "up",
334 NULL, /* role */
335 NULL, /* crypto */
336 NULL, /* auth */
337 NULL, /* passphrase */
338 NULL, /* ssid */
339 NULL};
340 char tmp[100], prefix[32];
341 int unit;
342 char remote[ETHER_ADDR_LEN];
343 char ssid[48], pass[80], auth[16], crypto[16], role[8];
344 int i;
346 /* the wireless interface must be configured to run NAS */
347 wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
348 sprintf(prefix, "wl%d_", unit);
349 if (nvram_match(strcat_r(prefix, "akm", tmp), "") && nvram_match(strcat_r(prefix, "auth_mode", tmp), "none")) {
350 return;
353 // wait until nas is up and running
354 char s[64];
355 int r;
357 r = 10;
358 while (f_read("/tmp/nas.lan.pid", s, sizeof(s)) <= 0) {
359 if (--r <= 0) {
360 cprintf("notify_nas: unable to find nas");
361 break;
363 sleep(1);
365 sleep(3);
368 /* find WDS link configuration */
369 wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
370 for (i = 0; i < 20; ++i) {
371 char mac[ETHER_ADDR_STR_LEN];
372 uint8 ea[ETHER_ADDR_LEN];
374 if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
375 ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
376 argv[4] = role;
377 argv[5] = crypto;
378 argv[6] = auth;
379 argv[7] = pass;
380 argv[8] = ssid;
382 cprintf("notify_nas: get_wds_wsec(%d,%d) crypto=%s", unit, i, argv[5]);
383 break;
386 /* did not find WDS link configuration, use wireless' */
387 if (i == 20) {
388 /* role */
389 argv[4] = "auto";
390 /* crypto */
391 argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
392 /* auth mode */
393 argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
394 /* passphrase */
395 argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
396 /* ssid */
397 argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
399 cprintf("notify_nas: i==MAX crypto=%s", argv[5]);
402 #if 0
403 char cl[512];
404 cl[0] = 0;
405 for (i = 0; argv[i]; ++i) {
406 strcat(cl, argv[i]);
407 strcat(cl, " ");
409 cprintf("notify_nas: %s", cl);
410 #endif
412 int pid;
413 _eval(argv, ">/dev/console", 0, &pid);
415 #endif
419 #endif // 0