allow coexistance of N build and AC build.
[tomato.git] / release / src / router / rc / wnas.c
blobe4be66fdf89ca7b931e37c82601e565345584038
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) {
68 return foreach_wif(1, NULL, security_on);
71 static int nas_starter(int idx, int unit, int subunit, void *param) {
72 char unit_str[] = "000000";
73 char lanN_ifname[] = "lanXX_ifname";
74 char lanN_ifnames[] = "lanXX_ifnames";
75 char br;
76 if(nvram_get_int(wl_nvname("bss_enabled", unit, subunit))) {
77 if (nvram_match(wl_nvname("mode", unit, subunit), "ap")) {
78 if (subunit > 0)
79 snprintf(unit_str, sizeof(unit_str), "%d.%d", unit, subunit);
80 else
81 snprintf(unit_str, sizeof(unit_str), "%d", unit);
83 for(br=3 ; br>=0 ; br--) {
84 char bridge[2] = "0";
85 if (br!=0)
86 bridge[0]+=br;
87 else
88 strcpy(bridge, "");
90 snprintf(lanN_ifname, sizeof(lanN_ifname), "lan%s_ifname", bridge);
91 snprintf(lanN_ifnames, sizeof(lanN_ifnames), "lan%s_ifnames", bridge);
93 if(strstr(nvram_safe_get(lanN_ifnames),nvram_safe_get(wl_nvname("ifname", unit, subunit))) != NULL) {
94 xstart("/usr/sbin/nas.sh", unit_str, nvram_safe_get(lanN_ifname));
95 sleep(3);
99 if(is_sta(idx, unit, subunit, NULL)) {
100 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
101 sleep(1);
104 return 0;
107 void start_nas(void)
109 if (!foreach_wif(1, NULL, security_on)) {
110 return;
113 #ifdef DEBUG_TIMING
114 struct sysinfo si;
115 sysinfo(&si);
116 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
117 #else
118 _dprintf("%s\n", __FUNCTION__);
119 #endif
121 #ifdef CONFIG_BCMWL5
122 setenv("UDP_BIND_IP", "127.0.0.1", 1);
123 eval("eapd");
124 unsetenv("UDP_BIND_IP");
125 eval("nas");
126 #else
127 mode_t m;
129 m = umask(0077);
131 if(nvram_get_int("nas_alternate")) {
132 foreach_wif(1, NULL, nas_starter);
133 } else {
134 if(strstr(nvram_safe_get("lan_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
135 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan");
136 if(strstr(nvram_safe_get("lan1_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
137 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan1");
138 if(strstr(nvram_safe_get("lan2_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
139 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan2");
140 if(strstr(nvram_safe_get("lan3_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
141 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan3");
143 if (foreach_wif(1, NULL, is_sta))
144 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
146 if (foreach_wif(1, NULL, is_sta))
147 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
148 umask(m);
149 #endif /* CONFIG_BCMWL5 */
151 if (wds_enable()) {
152 // notify NAS of all wds up ifaces upon startup
153 FILE *fd;
154 char *ifname, buf[256];
156 if ((fd = fopen("/proc/net/dev", "r")) != NULL) {
157 fgets(buf, sizeof(buf) - 1, fd); // header lines
158 fgets(buf, sizeof(buf) - 1, fd);
159 while (fgets(buf, sizeof(buf) - 1, fd)) {
160 if ((ifname = strchr(buf, ':')) == NULL) continue;
161 *ifname = 0;
162 if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
163 else ++ifname;
164 if (strstr(ifname, "wds")) {
165 notify_nas(ifname);
168 fclose(fd);
173 void stop_nas(void)
175 #ifdef DEBUG_TIMING
176 struct sysinfo si;
177 sysinfo(&si);
178 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
179 #else
180 _dprintf("%s\n", __FUNCTION__);
181 #endif
183 killall_tk("nas");
184 #ifdef CONFIG_BCMWL5
185 killall_tk("eapd");
186 #endif /* CONFIG_BCMWL5 */
189 void notify_nas(const char *ifname)
191 #ifdef DEBUG_TIMING
192 struct sysinfo si;
193 sysinfo(&si);
194 _dprintf("%s: ifname=%s uptime=%ld\n", __FUNCTION__, ifname, si.uptime);
195 #else
196 _dprintf("%s: ifname=%s\n", __FUNCTION__, ifname);
197 #endif
199 #ifdef CONFIG_BCMWL5
201 /* Inform driver to send up new WDS link event */
202 if (wl_iovar_setint((char *)ifname, "wds_enable", 1)) {
203 _dprintf("%s: set wds_enable failed\n", ifname);
206 #else /* !CONFIG_BCMWL5 */
208 if (!foreach_wif(1, NULL, security_on)) return;
210 int i;
211 int unit;
213 i = 10;
214 while (pidof("nas") == -1) {
215 _dprintf("waiting for nas i=%d\n", i);
216 if (--i < 0) {
217 syslog(LOG_ERR, "Unable to find nas");
218 break;
220 sleep(1);
222 sleep(5);
224 /* the wireless interface must be configured to run NAS */
225 wl_ioctl((char *)ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
227 xstart("nas4not", "lan", ifname, "up", "auto",
228 nvram_safe_get(wl_nvname("crypto", unit, 0)), // aes, tkip (aes+tkip ok?)
229 nvram_safe_get(wl_nvname("akm", unit, 0)), // psk (only?)
230 nvram_safe_get(wl_nvname("wpa_psk", unit, 0)), // shared key
231 nvram_safe_get(wl_nvname("ssid", unit, 0)) // ssid
234 #endif /* CONFIG_BCMWL5 */
240 #if 0 // old stuff for ref
244 void del_wds_wsec(int unit, int which)
246 char name[32];
248 sprintf(name, "wl%d_wds%d", unit, which);
249 nvram_unset(name);
255 xstart("nas",
256 nvram_match("wl_mode", "sta") ? "-S" : "-A",
257 "-H", "34954",
258 "-i", nvram_safe_get("wl_ifname"),
259 "-l", nvram_safe_get("lan_ifname"),
264 // WPA doesn't support shared key removed, handled during config set zzz
265 // if (strstr(nvram_safe_get("wl_akm"), "wpa") != NULL) {
266 // nvram_set("wl_auth", "0");
267 // }
269 // if ((nvram_match("wl_mode", "sta")) && (nvram_match("wl_akm", "psk psk2"))) {
270 // nvram_set("wl_akm", "psk2");
271 // }
273 // convert_wds();
278 static int get_wds_wsec(int unit, int which, char *mac, char *role, char *crypto, char *auth, char *ssid, char *pass)
280 char buf[512];
281 char *next;
283 sprintf(buf, "wl%d_wds%d", unit, which);
284 strlcpy(buf, nvram_safe_get(buf), sizeof(buf));
285 next = buf;
287 strcpy(mac, strsep(&next, ","));
288 if (!next) return 0;
290 strcpy(role, strsep(&next, ","));
291 if (!next) return 0;
293 strcpy(crypto, strsep(&next, ","));
294 if (!next) return 0;
296 strcpy(auth, strsep(&next, ","));
297 if (!next) return 0;
299 strcpy(ssid, strsep(&next, ","));
300 if (!next) return 0;
302 strcpy(pass, next);
303 return 1;
306 static void convert_wds(void)
308 char wds_mac[254];
309 char buf[254];
311 if (nvram_match("wl_wds", "")) { // For Router, accept all WDS link
312 strcpy(wds_mac, "*");
314 else { // For AP, assign remote WDS MAC
315 strlcpy(wds_mac, nvram_safe_get("wl_wds"), sizeof(wds_mac));
319 // For WPA-PSK mode, we want to convert wl_wds_mac to wl0_wds0 ... wl0_wds255
320 if (strstr(nvram_safe_get("wl_akm"), "psk")) {
321 char wl_wds[32];
322 int i = 0;
323 int j;
324 char mac[254];
325 char *next;
327 foreach(mac, wds_mac, next) {
328 snprintf(wl_wds, sizeof(wl_wds), "wl0_wds%d", i);
329 snprintf(buf, sizeof(buf), "%s,auto,%s,%s,%s,%s",
330 mac,
331 nvram_safe_get("wl_crypto"),
332 nvram_safe_get("wl_akm"),
333 nvram_safe_get("wl_ssid"),
334 nvram_safe_get("wl_wpa_psk"));
336 nvram_set(wl_wds, buf);
337 i++;
340 for (j = i; j < 20; j++)
341 del_wds_wsec(0, j);
346 #if 0
347 void notify_nas(char *ifname)
349 char *argv[] = {"nas4not", "lan", ifname, "up",
350 NULL, /* role */
351 NULL, /* crypto */
352 NULL, /* auth */
353 NULL, /* passphrase */
354 NULL, /* ssid */
355 NULL};
356 char tmp[100], prefix[32];
357 int unit;
358 char remote[ETHER_ADDR_LEN];
359 char ssid[48], pass[80], auth[16], crypto[16], role[8];
360 int i;
362 /* the wireless interface must be configured to run NAS */
363 wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
364 sprintf(prefix, "wl%d_", unit);
365 if (nvram_match(strcat_r(prefix, "akm", tmp), "") && nvram_match(strcat_r(prefix, "auth_mode", tmp), "none")) {
366 return;
369 // wait until nas is up and running
370 char s[64];
371 int r;
373 r = 10;
374 while (f_read("/tmp/nas.lan.pid", s, sizeof(s)) <= 0) {
375 if (--r <= 0) {
376 cprintf("notify_nas: unable to find nas");
377 break;
379 sleep(1);
381 sleep(3);
384 /* find WDS link configuration */
385 wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
386 for (i = 0; i < 20; ++i) {
387 char mac[ETHER_ADDR_STR_LEN];
388 uint8 ea[ETHER_ADDR_LEN];
390 if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
391 ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
392 argv[4] = role;
393 argv[5] = crypto;
394 argv[6] = auth;
395 argv[7] = pass;
396 argv[8] = ssid;
398 cprintf("notify_nas: get_wds_wsec(%d,%d) crypto=%s", unit, i, argv[5]);
399 break;
402 /* did not find WDS link configuration, use wireless' */
403 if (i == 20) {
404 /* role */
405 argv[4] = "auto";
406 /* crypto */
407 argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
408 /* auth mode */
409 argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
410 /* passphrase */
411 argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
412 /* ssid */
413 argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
415 cprintf("notify_nas: i==MAX crypto=%s", argv[5]);
418 #if 0
419 char cl[512];
420 cl[0] = 0;
421 for (i = 0; argv[i]; ++i) {
422 strcat(cl, argv[i]);
423 strcat(cl, " ");
425 cprintf("notify_nas: %s", cl);
426 #endif
428 int pid;
429 _eval(argv, ">/dev/console", 0, &pid);
431 #endif
435 #endif // 0