EXPERIMENTAL VLAN/VID mapping GUI
[tomato.git] / release / src / router / rc / wnas.c
blob7c0d4ce8fbf6d4396be50db731cb51347f43e7f9
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 #ifdef TCONFIG_VLAN
92 if(strstr(nvram_safe_get("lan1_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
93 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan1");
94 if(strstr(nvram_safe_get("lan2_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
95 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan2");
96 if(strstr(nvram_safe_get("lan3_ifnames"),nvram_safe_get("wl0_ifname")) != NULL)
97 xstart("nas", "/etc/nas.conf", "/var/run/nas.pid", "lan3");
98 #endif
99 if (foreach_wif(1, NULL, is_sta))
100 xstart("nas", "/etc/nas.wan.conf", "/var/run/nas.wan.pid", "wan");
101 umask(m);
102 #endif /* CONFIG_BCMWL5 */
104 if (wds_enable()) {
105 // notify NAS of all wds up ifaces upon startup
106 FILE *fd;
107 char *ifname, buf[256];
109 if ((fd = fopen("/proc/net/dev", "r")) != NULL) {
110 fgets(buf, sizeof(buf) - 1, fd); // header lines
111 fgets(buf, sizeof(buf) - 1, fd);
112 while (fgets(buf, sizeof(buf) - 1, fd)) {
113 if ((ifname = strchr(buf, ':')) == NULL) continue;
114 *ifname = 0;
115 if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
116 else ++ifname;
117 if (strstr(ifname, "wds")) {
118 notify_nas(ifname);
121 fclose(fd);
126 void stop_nas(void)
128 #ifdef DEBUG_TIMING
129 struct sysinfo si;
130 sysinfo(&si);
131 _dprintf("%s: uptime=%ld\n", __FUNCTION__, si.uptime);
132 #else
133 _dprintf("%s\n", __FUNCTION__);
134 #endif
136 killall_tk("nas");
137 #ifdef CONFIG_BCMWL5
138 killall_tk("eapd");
139 #endif /* CONFIG_BCMWL5 */
142 void notify_nas(const char *ifname)
144 #ifdef DEBUG_TIMING
145 struct sysinfo si;
146 sysinfo(&si);
147 _dprintf("%s: ifname=%s uptime=%ld\n", __FUNCTION__, ifname, si.uptime);
148 #else
149 _dprintf("%s: ifname=%s\n", __FUNCTION__, ifname);
150 #endif
152 #ifdef CONFIG_BCMWL5
154 /* Inform driver to send up new WDS link event */
155 if (wl_iovar_setint((char *)ifname, "wds_enable", 1)) {
156 _dprintf("%s: set wds_enable failed\n", ifname);
159 #else /* !CONFIG_BCMWL5 */
161 if (!foreach_wif(1, NULL, security_on)) return;
163 int i;
164 int unit;
166 i = 10;
167 while (pidof("nas") == -1) {
168 _dprintf("waiting for nas i=%d\n", i);
169 if (--i < 0) {
170 syslog(LOG_ERR, "Unable to find nas");
171 break;
173 sleep(1);
175 sleep(5);
177 /* the wireless interface must be configured to run NAS */
178 wl_ioctl((char *)ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
180 xstart("nas4not", "lan", ifname, "up", "auto",
181 nvram_safe_get(wl_nvname("crypto", unit, 0)), // aes, tkip (aes+tkip ok?)
182 nvram_safe_get(wl_nvname("akm", unit, 0)), // psk (only?)
183 nvram_safe_get(wl_nvname("wpa_psk", unit, 0)), // shared key
184 nvram_safe_get(wl_nvname("ssid", unit, 0)) // ssid
187 #endif /* CONFIG_BCMWL5 */
193 #if 0 // old stuff for ref
197 void del_wds_wsec(int unit, int which)
199 char name[32];
201 sprintf(name, "wl%d_wds%d", unit, which);
202 nvram_unset(name);
208 xstart("nas",
209 nvram_match("wl_mode", "sta") ? "-S" : "-A",
210 "-H", "34954",
211 "-i", nvram_safe_get("wl_ifname"),
212 "-l", nvram_safe_get("lan_ifname"),
217 // WPA doesn't support shared key removed, handled during config set zzz
218 // if (strstr(nvram_safe_get("wl_akm"), "wpa") != NULL) {
219 // nvram_set("wl_auth", "0");
220 // }
222 // if ((nvram_match("wl_mode", "sta")) && (nvram_match("wl_akm", "psk psk2"))) {
223 // nvram_set("wl_akm", "psk2");
224 // }
226 // convert_wds();
231 static int get_wds_wsec(int unit, int which, char *mac, char *role, char *crypto, char *auth, char *ssid, char *pass)
233 char buf[512];
234 char *next;
236 sprintf(buf, "wl%d_wds%d", unit, which);
237 strlcpy(buf, nvram_safe_get(buf), sizeof(buf));
238 next = buf;
240 strcpy(mac, strsep(&next, ","));
241 if (!next) return 0;
243 strcpy(role, strsep(&next, ","));
244 if (!next) return 0;
246 strcpy(crypto, strsep(&next, ","));
247 if (!next) return 0;
249 strcpy(auth, strsep(&next, ","));
250 if (!next) return 0;
252 strcpy(ssid, strsep(&next, ","));
253 if (!next) return 0;
255 strcpy(pass, next);
256 return 1;
259 static void convert_wds(void)
261 char wds_mac[254];
262 char buf[254];
264 if (nvram_match("wl_wds", "")) { // For Router, accept all WDS link
265 strcpy(wds_mac, "*");
267 else { // For AP, assign remote WDS MAC
268 strlcpy(wds_mac, nvram_safe_get("wl_wds"), sizeof(wds_mac));
272 // For WPA-PSK mode, we want to convert wl_wds_mac to wl0_wds0 ... wl0_wds255
273 if (strstr(nvram_safe_get("wl_akm"), "psk")) {
274 char wl_wds[32];
275 int i = 0;
276 int j;
277 char mac[254];
278 char *next;
280 foreach(mac, wds_mac, next) {
281 snprintf(wl_wds, sizeof(wl_wds), "wl0_wds%d", i);
282 snprintf(buf, sizeof(buf), "%s,auto,%s,%s,%s,%s",
283 mac,
284 nvram_safe_get("wl_crypto"),
285 nvram_safe_get("wl_akm"),
286 nvram_safe_get("wl_ssid"),
287 nvram_safe_get("wl_wpa_psk"));
289 nvram_set(wl_wds, buf);
290 i++;
293 for (j = i; j < 20; j++)
294 del_wds_wsec(0, j);
299 #if 0
300 void notify_nas(char *ifname)
302 char *argv[] = {"nas4not", "lan", ifname, "up",
303 NULL, /* role */
304 NULL, /* crypto */
305 NULL, /* auth */
306 NULL, /* passphrase */
307 NULL, /* ssid */
308 NULL};
309 char tmp[100], prefix[32];
310 int unit;
311 char remote[ETHER_ADDR_LEN];
312 char ssid[48], pass[80], auth[16], crypto[16], role[8];
313 int i;
315 /* the wireless interface must be configured to run NAS */
316 wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
317 sprintf(prefix, "wl%d_", unit);
318 if (nvram_match(strcat_r(prefix, "akm", tmp), "") && nvram_match(strcat_r(prefix, "auth_mode", tmp), "none")) {
319 return;
322 // wait until nas is up and running
323 char s[64];
324 int r;
326 r = 10;
327 while (f_read("/tmp/nas.lan.pid", s, sizeof(s)) <= 0) {
328 if (--r <= 0) {
329 cprintf("notify_nas: unable to find nas");
330 break;
332 sleep(1);
334 sleep(3);
337 /* find WDS link configuration */
338 wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
339 for (i = 0; i < 20; ++i) {
340 char mac[ETHER_ADDR_STR_LEN];
341 uint8 ea[ETHER_ADDR_LEN];
343 if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
344 ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
345 argv[4] = role;
346 argv[5] = crypto;
347 argv[6] = auth;
348 argv[7] = pass;
349 argv[8] = ssid;
351 cprintf("notify_nas: get_wds_wsec(%d,%d) crypto=%s", unit, i, argv[5]);
352 break;
355 /* did not find WDS link configuration, use wireless' */
356 if (i == 20) {
357 /* role */
358 argv[4] = "auto";
359 /* crypto */
360 argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
361 /* auth mode */
362 argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
363 /* passphrase */
364 argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
365 /* ssid */
366 argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
368 cprintf("notify_nas: i==MAX crypto=%s", argv[5]);
371 #if 0
372 char cl[512];
373 cl[0] = 0;
374 for (i = 0; argv[i]; ++i) {
375 strcat(cl, argv[i]);
376 strcat(cl, " ");
378 cprintf("notify_nas: %s", cl);
379 #endif
381 int pid;
382 _eval(argv, ">/dev/console", 0, &pid);
384 #endif
388 #endif // 0