cosmetics
[tomato.git] / release / src / router / rc / wnas.c
blob3b91b99e2894d06521e61d14c9ca97e70130c21b
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 setenv("UDP_BIND_IP", "127.0.0.1", 1);
83 eval("eapd");
84 unsetenv("UDP_BIND_IP");
85 eval("nas");
86 #else
87 mode_t m;
89 m = umask(0077);
90 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan");
91 if (foreach_wif(1, NULL, is_sta))
92 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
93 umask(m);
94 #endif /* CONFIG_BCMWL5 */
96 if (wds_enable()) {
97 // notify NAS of all wds up ifaces upon startup
98 FILE *fd;
99 char *ifname, buf[256];
101 if ((fd = fopen("/proc/net/dev", "r")) != NULL) {
102 fgets(buf, sizeof(buf) - 1, fd); // header lines
103 fgets(buf, sizeof(buf) - 1, fd);
104 while (fgets(buf, sizeof(buf) - 1, fd)) {
105 if ((ifname = strchr(buf, ':')) == NULL) continue;
106 *ifname = 0;
107 if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
108 else ++ifname;
109 if (strstr(ifname, "wds")) {
110 notify_nas(ifname);
113 fclose(fd);
118 void stop_nas(void)
120 #ifdef DEBUG_TIMING
121 struct sysinfo si;
122 sysinfo(&si);
123 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
124 #else
125 _dprintf("%s\n", __FUNCTION__);
126 #endif
128 killall_tk("nas");
129 #ifdef CONFIG_BCMWL5
130 killall_tk("eapd");
131 #endif /* CONFIG_BCMWL5 */
134 void notify_nas(const char *ifname)
136 #ifdef DEBUG_TIMING
137 struct sysinfo si;
138 sysinfo(&si);
139 _dprintf("%s: ifname=%s uptime=%ld\n", __FUNCTION__, ifname, si.uptime);
140 #else
141 _dprintf("%s: ifname=%s\n", __FUNCTION__, ifname);
142 #endif
144 #ifdef CONFIG_BCMWL5
146 /* Inform driver to send up new WDS link event */
147 if (wl_iovar_setint((char *)ifname, "wds_enable", 1)) {
148 _dprintf("%s: set wds_enable failed\n", ifname);
151 #else /* !CONFIG_BCMWL5 */
153 if (!foreach_wif(1, NULL, security_on)) return;
155 int i;
156 int unit;
158 i = 10;
159 while (pidof("nas") == -1) {
160 _dprintf("waiting for nas i=%d\n", i);
161 if (--i < 0) {
162 syslog(LOG_ERR, "Unable to find nas");
163 break;
165 sleep(1);
167 sleep(5);
169 /* the wireless interface must be configured to run NAS */
170 wl_ioctl((char *)ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
172 xstart("nas4not", "lan", ifname, "up", "auto",
173 nvram_safe_get(wl_nvname("crypto", unit, 0)), // aes, tkip (aes+tkip ok?)
174 nvram_safe_get(wl_nvname("akm", unit, 0)), // psk (only?)
175 nvram_safe_get(wl_nvname("wpa_psk", unit, 0)), // shared key
176 nvram_safe_get(wl_nvname("ssid", unit, 0)) // ssid
179 #endif /* CONFIG_BCMWL5 */
185 #if 0 // old stuff for ref
189 void del_wds_wsec(int unit, int which)
191 char name[32];
193 sprintf(name, "wl%d_wds%d", unit, which);
194 nvram_unset(name);
200 xstart("nas",
201 nvram_match("wl_mode", "sta") ? "-S" : "-A",
202 "-H", "34954",
203 "-i", nvram_safe_get("wl_ifname"),
204 "-l", nvram_safe_get("lan_ifname"),
209 // WPA doesn't support shared key removed, handled during config set zzz
210 // if (strstr(nvram_safe_get("wl_akm"), "wpa") != NULL) {
211 // nvram_set("wl_auth", "0");
212 // }
214 // if ((nvram_match("wl_mode", "sta")) && (nvram_match("wl_akm", "psk psk2"))) {
215 // nvram_set("wl_akm", "psk2");
216 // }
218 // convert_wds();
223 static int get_wds_wsec(int unit, int which, char *mac, char *role, char *crypto, char *auth, char *ssid, char *pass)
225 char buf[512];
226 char *next;
228 sprintf(buf, "wl%d_wds%d", unit, which);
229 strlcpy(buf, nvram_safe_get(buf), sizeof(buf));
230 next = buf;
232 strcpy(mac, strsep(&next, ","));
233 if (!next) return 0;
235 strcpy(role, strsep(&next, ","));
236 if (!next) return 0;
238 strcpy(crypto, strsep(&next, ","));
239 if (!next) return 0;
241 strcpy(auth, strsep(&next, ","));
242 if (!next) return 0;
244 strcpy(ssid, strsep(&next, ","));
245 if (!next) return 0;
247 strcpy(pass, next);
248 return 1;
251 static void convert_wds(void)
253 char wds_mac[254];
254 char buf[254];
256 if (nvram_match("wl_wds", "")) { // For Router, accept all WDS link
257 strcpy(wds_mac, "*");
259 else { // For AP, assign remote WDS MAC
260 strlcpy(wds_mac, nvram_safe_get("wl_wds"), sizeof(wds_mac));
264 // For WPA-PSK mode, we want to convert wl_wds_mac to wl0_wds0 ... wl0_wds255
265 if (strstr(nvram_safe_get("wl_akm"), "psk")) {
266 char wl_wds[32];
267 int i = 0;
268 int j;
269 char mac[254];
270 char *next;
272 foreach(mac, wds_mac, next) {
273 snprintf(wl_wds, sizeof(wl_wds), "wl0_wds%d", i);
274 snprintf(buf, sizeof(buf), "%s,auto,%s,%s,%s,%s",
275 mac,
276 nvram_safe_get("wl_crypto"),
277 nvram_safe_get("wl_akm"),
278 nvram_safe_get("wl_ssid"),
279 nvram_safe_get("wl_wpa_psk"));
281 nvram_set(wl_wds, buf);
282 i++;
285 for (j = i; j < 20; j++)
286 del_wds_wsec(0, j);
291 #if 0
292 void notify_nas(char *ifname)
294 char *argv[] = {"nas4not", "lan", ifname, "up",
295 NULL, /* role */
296 NULL, /* crypto */
297 NULL, /* auth */
298 NULL, /* passphrase */
299 NULL, /* ssid */
300 NULL};
301 char tmp[100], prefix[32];
302 int unit;
303 char remote[ETHER_ADDR_LEN];
304 char ssid[48], pass[80], auth[16], crypto[16], role[8];
305 int i;
307 /* the wireless interface must be configured to run NAS */
308 wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
309 sprintf(prefix, "wl%d_", unit);
310 if (nvram_match(strcat_r(prefix, "akm", tmp), "") && nvram_match(strcat_r(prefix, "auth_mode", tmp), "none")) {
311 return;
314 // wait until nas is up and running
315 char s[64];
316 int r;
318 r = 10;
319 while (f_read("/tmp/nas.lan.pid", s, sizeof(s)) <= 0) {
320 if (--r <= 0) {
321 cprintf("notify_nas: unable to find nas");
322 break;
324 sleep(1);
326 sleep(3);
329 /* find WDS link configuration */
330 wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
331 for (i = 0; i < 20; ++i) {
332 char mac[ETHER_ADDR_STR_LEN];
333 uint8 ea[ETHER_ADDR_LEN];
335 if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
336 ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
337 argv[4] = role;
338 argv[5] = crypto;
339 argv[6] = auth;
340 argv[7] = pass;
341 argv[8] = ssid;
343 cprintf("notify_nas: get_wds_wsec(%d,%d) crypto=%s", unit, i, argv[5]);
344 break;
347 /* did not find WDS link configuration, use wireless' */
348 if (i == 20) {
349 /* role */
350 argv[4] = "auto";
351 /* crypto */
352 argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
353 /* auth mode */
354 argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
355 /* passphrase */
356 argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
357 /* ssid */
358 argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
360 cprintf("notify_nas: i==MAX crypto=%s", argv[5]);
363 #if 0
364 char cl[512];
365 cl[0] = 0;
366 for (i = 0; argv[i]; ++i) {
367 strcat(cl, argv[i]);
368 strcat(cl, " ");
370 cprintf("notify_nas: %s", cl);
371 #endif
373 int pid;
374 _eval(argv, ">/dev/console", 0, &pid);
376 #endif
380 #endif // 0