WLAN can now be assigned to any LAN bridge. Changing VLAN/bridge settings no longer...
[tomato.git] / release / src / router / rc / wnas.c
blob509076688d254c3296e2c6486706193bfeacb873
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 void start_nas(void)
69 if (!foreach_wif(1, NULL, security_on)) {
70 return;
73 #ifdef DEBUG_TIMING
74 struct sysinfo si;
75 sysinfo(&si);
76 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
77 #else
78 _dprintf("%s\n", __FUNCTION__);
79 #endif
81 #ifdef CONFIG_BCMWL5
82 xstart("eapd");
83 usleep(250000);
84 xstart("nas");
85 #else
86 mode_t m;
88 m = umask(0077);
89 if(strstr(nvram_safe_get("lan_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
90 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan");
91 if(strstr(nvram_safe_get("lan1_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
92 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan1");
93 if(strstr(nvram_safe_get("lan2_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
94 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan2");
95 if(strstr(nvram_safe_get("lan3_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
96 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan3");
98 if (foreach_wif(1, NULL, is_sta))
99 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
100 umask(m);
101 #endif /* CONFIG_BCMWL5 */
103 if (wds_enable()) {
104 // notify NAS of all wds up ifaces upon startup
105 FILE *fd;
106 char *ifname, buf[256];
108 if ((fd = fopen("/proc/net/dev", "r")) != NULL) {
109 fgets(buf, sizeof(buf) - 1, fd); // header lines
110 fgets(buf, sizeof(buf) - 1, fd);
111 while (fgets(buf, sizeof(buf) - 1, fd)) {
112 if ((ifname = strchr(buf, ':')) == NULL) continue;
113 *ifname = 0;
114 if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
115 else ++ifname;
116 if (strstr(ifname, "wds")) {
117 notify_nas(ifname);
120 fclose(fd);
125 void stop_nas(void)
127 #ifdef DEBUG_TIMING
128 struct sysinfo si;
129 sysinfo(&si);
130 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
131 #else
132 _dprintf("%s\n", __FUNCTION__);
133 #endif
135 killall_tk("nas");
136 #ifdef CONFIG_BCMWL5
137 killall_tk("eapd");
138 #endif /* CONFIG_BCMWL5 */
141 void notify_nas(const char *ifname)
143 #ifdef DEBUG_TIMING
144 struct sysinfo si;
145 sysinfo(&si);
146 _dprintf("%s: ifname=%s uptime=%ld\n", __FUNCTION__, ifname, si.uptime);
147 #else
148 _dprintf("%s: ifname=%s\n", __FUNCTION__, ifname);
149 #endif
151 #ifdef CONFIG_BCMWL5
153 /* Inform driver to send up new WDS link event */
154 if (wl_iovar_setint((char *)ifname, "wds_enable", 1)) {
155 _dprintf("%s: set wds_enable failed\n", ifname);
158 #else /* !CONFIG_BCMWL5 */
160 if (!foreach_wif(1, NULL, security_on)) return;
162 int i;
163 int unit;
165 i = 10;
166 while (pidof("nas") == -1) {
167 _dprintf("waiting for nas i=%d\n", i);
168 if (--i < 0) {
169 syslog(LOG_ERR, "Unable to find nas");
170 break;
172 sleep(1);
174 sleep(5);
176 /* the wireless interface must be configured to run NAS */
177 wl_ioctl((char *)ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
179 xstart("nas4not", "lan", ifname, "up", "auto",
180 nvram_safe_get(wl_nvname("crypto", unit, 0)), // aes, tkip (aes+tkip ok?)
181 nvram_safe_get(wl_nvname("akm", unit, 0)), // psk (only?)
182 nvram_safe_get(wl_nvname("wpa_psk", unit, 0)), // shared key
183 nvram_safe_get(wl_nvname("ssid", unit, 0)) // ssid
186 #endif /* CONFIG_BCMWL5 */
192 #if 0 // old stuff for ref
196 void del_wds_wsec(int unit, int which)
198 char name[32];
200 sprintf(name, "wl%d_wds%d", unit, which);
201 nvram_unset(name);
207 xstart("nas",
208 nvram_match("wl_mode", "sta") ? "-S" : "-A",
209 "-H", "34954",
210 "-i", nvram_safe_get("wl_ifname"),
211 "-l", nvram_safe_get("lan_ifname"),
216 // WPA doesn't support shared key removed, handled during config set zzz
217 // if (strstr(nvram_safe_get("wl_akm"), "wpa") != NULL) {
218 // nvram_set("wl_auth", "0");
219 // }
221 // if ((nvram_match("wl_mode", "sta")) && (nvram_match("wl_akm", "psk psk2"))) {
222 // nvram_set("wl_akm", "psk2");
223 // }
225 // convert_wds();
230 static int get_wds_wsec(int unit, int which, char *mac, char *role, char *crypto, char *auth, char *ssid, char *pass)
232 char buf[512];
233 char *next;
235 sprintf(buf, "wl%d_wds%d", unit, which);
236 strlcpy(buf, nvram_safe_get(buf), sizeof(buf));
237 next = buf;
239 strcpy(mac, strsep(&next, ","));
240 if (!next) return 0;
242 strcpy(role, strsep(&next, ","));
243 if (!next) return 0;
245 strcpy(crypto, strsep(&next, ","));
246 if (!next) return 0;
248 strcpy(auth, strsep(&next, ","));
249 if (!next) return 0;
251 strcpy(ssid, strsep(&next, ","));
252 if (!next) return 0;
254 strcpy(pass, next);
255 return 1;
258 static void convert_wds(void)
260 char wds_mac[254];
261 char buf[254];
263 if (nvram_match("wl_wds", "")) { // For Router, accept all WDS link
264 strcpy(wds_mac, "*");
266 else { // For AP, assign remote WDS MAC
267 strlcpy(wds_mac, nvram_safe_get("wl_wds"), sizeof(wds_mac));
271 // For WPA-PSK mode, we want to convert wl_wds_mac to wl0_wds0 ... wl0_wds255
272 if (strstr(nvram_safe_get("wl_akm"), "psk")) {
273 char wl_wds[32];
274 int i = 0;
275 int j;
276 char mac[254];
277 char *next;
279 foreach(mac, wds_mac, next) {
280 snprintf(wl_wds, sizeof(wl_wds), "wl0_wds%d", i);
281 snprintf(buf, sizeof(buf), "%s,auto,%s,%s,%s,%s",
282 mac,
283 nvram_safe_get("wl_crypto"),
284 nvram_safe_get("wl_akm"),
285 nvram_safe_get("wl_ssid"),
286 nvram_safe_get("wl_wpa_psk"));
288 nvram_set(wl_wds, buf);
289 i++;
292 for (j = i; j < 20; j++)
293 del_wds_wsec(0, j);
298 #if 0
299 void notify_nas(char *ifname)
301 char *argv[] = {"nas4not", "lan", ifname, "up",
302 NULL, /* role */
303 NULL, /* crypto */
304 NULL, /* auth */
305 NULL, /* passphrase */
306 NULL, /* ssid */
307 NULL};
308 char tmp[100], prefix[32];
309 int unit;
310 char remote[ETHER_ADDR_LEN];
311 char ssid[48], pass[80], auth[16], crypto[16], role[8];
312 int i;
314 /* the wireless interface must be configured to run NAS */
315 wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
316 sprintf(prefix, "wl%d_", unit);
317 if (nvram_match(strcat_r(prefix, "akm", tmp), "") && nvram_match(strcat_r(prefix, "auth_mode", tmp), "none")) {
318 return;
321 // wait until nas is up and running
322 char s[64];
323 int r;
325 r = 10;
326 while (f_read("/tmp/nas.lan.pid", s, sizeof(s)) <= 0) {
327 if (--r <= 0) {
328 cprintf("notify_nas: unable to find nas");
329 break;
331 sleep(1);
333 sleep(3);
336 /* find WDS link configuration */
337 wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
338 for (i = 0; i < 20; ++i) {
339 char mac[ETHER_ADDR_STR_LEN];
340 uint8 ea[ETHER_ADDR_LEN];
342 if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
343 ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
344 argv[4] = role;
345 argv[5] = crypto;
346 argv[6] = auth;
347 argv[7] = pass;
348 argv[8] = ssid;
350 cprintf("notify_nas: get_wds_wsec(%d,%d) crypto=%s", unit, i, argv[5]);
351 break;
354 /* did not find WDS link configuration, use wireless' */
355 if (i == 20) {
356 /* role */
357 argv[4] = "auto";
358 /* crypto */
359 argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
360 /* auth mode */
361 argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
362 /* passphrase */
363 argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
364 /* ssid */
365 argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
367 cprintf("notify_nas: i==MAX crypto=%s", argv[5]);
370 #if 0
371 char cl[512];
372 cl[0] = 0;
373 for (i = 0; argv[i]; ++i) {
374 strcat(cl, argv[i]);
375 strcat(cl, " ");
377 cprintf("notify_nas: %s", cl);
378 #endif
380 int pid;
381 _eval(argv, ">/dev/console", 0, &pid);
383 #endif
387 #endif // 0