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
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.
33 Copyright (C) 2005 Felix Fietkau <nbd@vd-s.ath.cx>
38 Modified for Tomato Firmware
39 Portions, Copyright (C) 2006-2009 Jonathan Zarate
46 typedef u_int64_t u64
;
47 typedef u_int32_t u32
;
48 typedef u_int16_t u16
;
52 #include <linux/types.h>
53 #include <linux/sockios.h>
54 #include <linux/ethtool.h>
55 #include <sys/ioctl.h>
56 #include <net/if_arp.h>
57 #include <arpa/inet.h>
61 #include <bcmparams.h>
64 #ifndef WL_BSS_INFO_VERSION
65 #error WL_BSS_INFO_VERSION
67 #if WL_BSS_INFO_VERSION >= 108
73 static void set_lan_hostname(const char *wan_hostname
)
78 nvram_set("lan_hostname", wan_hostname
);
79 if ((wan_hostname
== NULL
) || (*wan_hostname
== 0)) {
80 /* derive from et0 mac address */
81 s
= nvram_get("et0macaddr");
82 if (s
&& strlen(s
) >= 17) {
84 sprintf(hostname
, "RT-%c%c%c%c%c%c%c%c%c%c%c%c",
85 s
[0], s
[1], s
[3], s
[4], s
[6], s
[7],
86 s
[9], s
[10], s
[12], s
[13], s
[15], s
[16]);
88 if ((f
= fopen("/proc/sys/kernel/hostname", "w"))) {
92 nvram_set("lan_hostname", hostname
);
96 if ((f
= fopen("/etc/hosts", "w"))) {
97 fprintf(f
, "127.0.0.1 localhost\n");
98 if ((s
= nvram_get("lan_ipaddr")) && (*s
))
99 fprintf(f
, "%s %s\n", s
, nvram_safe_get("lan_hostname"));
101 if (ipv6_enabled()) {
102 fprintf(f
, "::1 localhost\n");
103 s
= ipv6_router_address(NULL
);
104 if (*s
) fprintf(f
, "%s %s\n", s
, nvram_safe_get("lan_hostname"));
111 void set_host_domain_name(void)
115 s
= nvram_safe_get("wan_hostname");
116 sethostname(s
, strlen(s
));
119 s
= nvram_get("wan_domain");
120 if ((s
== NULL
) || (*s
== 0)) s
= nvram_safe_get("wan_get_domain");
121 setdomainname(s
, strlen(s
));
124 static int wlconf(char *ifname
, int unit
, int subunit
)
129 if (/* !wl_probe(ifname) && */ unit
>= 0) {
130 // validate nvram settings for wireless i/f
131 snprintf(wl
, sizeof(wl
), "--wl%d", unit
);
132 eval("nvram", "validate", wl
);
135 r
= eval("wlconf", ifname
, "up");
137 if (unit
>= 0 && subunit
<= 0) {
138 // setup primary wl interface
139 nvram_set("rrules_radio", "-1");
141 eval("wl", "-i", ifname
, "antdiv", nvram_safe_get(wl_nvname("antdiv", unit
, 0)));
142 eval("wl", "-i", ifname
, "txant", nvram_safe_get(wl_nvname("txant", unit
, 0)));
143 eval("wl", "-i", ifname
, "txpwr1", "-o", "-m", nvram_get_int(wl_nvname("txpwr", unit
, 0)) ? nvram_safe_get(wl_nvname("txpwr", unit
, 0)) : "-1");
144 eval("wl", "-i", ifname
, "interference", nvram_safe_get(wl_nvname("mitigation", unit
, 0)));
147 if (wl_client(unit
, subunit
)) {
148 if (nvram_match(wl_nvname("mode", unit
, subunit
), "wet")) {
149 ifconfig(ifname
, IFUP
|IFF_ALLMULTI
, NULL
, NULL
);
151 if (nvram_get_int(wl_nvname("radio", unit
, 0))) {
152 snprintf(wl
, sizeof(wl
), "%d", unit
);
153 xstart("radio", "join", wl
);
160 // -----------------------------------------------------------------------------
163 static void emf_mfdb_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
165 char word
[256], *next
;
168 /* Add/Delete MFDB entries corresponding to new interface */
169 foreach (word
, nvram_safe_get("emf_entry"), next
) {
171 mgrp
= strsep(&ifname
, ":");
173 if ((mgrp
== NULL
) || (ifname
== NULL
)) continue;
175 /* Add/Delete MFDB entry using the group addr and interface */
176 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
177 eval("emf", ((add
) ? "add" : "del"), "mfdb", lan_ifname
, mgrp
, ifname
);
182 static void emf_uffp_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
184 char word
[256], *next
;
187 /* Add/Delete UFFP entries corresponding to new interface */
188 foreach (word
, nvram_safe_get("emf_uffp_entry"), next
) {
191 if (ifname
== NULL
) continue;
193 /* Add/Delete UFFP entry for the interface */
194 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
195 eval("emf", ((add
) ? "add" : "del"), "uffp", lan_ifname
, ifname
);
200 static void emf_rtport_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
202 char word
[256], *next
;
205 /* Add/Delete RTPORT entries corresponding to new interface */
206 foreach (word
, nvram_safe_get("emf_rtport_entry"), next
) {
209 if (ifname
== NULL
) continue;
211 /* Add/Delete RTPORT entry for the interface */
212 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
213 eval("emf", ((add
) ? "add" : "del"), "rtport", lan_ifname
, ifname
);
218 static void start_emf(char *lan_ifname
)
221 eval("emf", "start", lan_ifname
);
223 /* Add the static MFDB entries */
224 emf_mfdb_update(lan_ifname
, NULL
, 1);
226 /* Add the UFFP entries */
227 emf_uffp_update(lan_ifname
, NULL
, 1);
229 /* Add the RTPORT entries */
230 emf_rtport_update(lan_ifname
, NULL
, 1);
233 static void stop_emf(char *lan_ifname
)
235 eval("emf", "stop", lan_ifname
);
236 eval("igs", "del", "bridge", lan_ifname
);
237 eval("emf", "del", "bridge", lan_ifname
);
241 // -----------------------------------------------------------------------------
243 /* Set initial QoS mode for all et interfaces that are up. */
244 void set_et_qos_mode(int sfd
)
249 struct ethtool_drvinfo info
;
251 qos
= (strcmp(nvram_safe_get("wl_wme"), "off") != 0);
252 for (i
= 1; i
<= DEV_NUMIFS
; i
++) {
254 if (ioctl(sfd
, SIOCGIFNAME
, &ifr
)) continue;
255 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
)) continue;
256 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) continue;
258 if (ioctl(sfd
, SIOCGIFFLAGS
, &ifr
)) continue;
259 /* if up (wan may not be up yet at this point) */
260 if (ifr
.ifr_flags
& IFF_UP
) {
261 ifrdata
= ifr
.ifr_data
;
262 memset(&info
, 0, sizeof(info
));
263 info
.cmd
= ETHTOOL_GDRVINFO
;
264 ifr
.ifr_data
= (caddr_t
)&info
;
265 if (ioctl(sfd
, SIOCETHTOOL
, &ifr
) >= 0) {
266 /* Set QoS for et & bcm57xx devices */
267 if (!strncmp(info
.driver
, "et", 2) ||
268 !strncmp(info
.driver
, "bcm57", 5)) {
269 ifr
.ifr_data
= (caddr_t
)&qos
;
270 ioctl(sfd
, SIOCSETCQOS
, &ifr
);
273 ifr
.ifr_data
= ifrdata
;
278 static void check_afterburner(void)
282 if (nvram_match("wl_afterburner", "off")) return;
283 if ((p
= nvram_get("boardflags")) == NULL
) return;
285 if (strcmp(p
, "0x0118") == 0) { // G 2.2, 3.0, 3.1
288 else if (strcmp(p
, "0x0188") == 0) { // G 2.0
291 else if (strcmp(p
, "0x2558") == 0) { // G 4.0, GL 1.0, 1.1
298 nvram_set("boardflags", p
);
300 if (!nvram_match("debug_abrst", "0")) {
311 bf = strtoul(p, &p, 0);
312 if ((*p == 0) && ((bf & BFL_AFTERBURNER) == 0)) {
313 sprintf(s, "0x%04lX", bf | BFL_AFTERBURNER);
314 nvram_set("boardflags", s);
319 static int set_wlmac(int idx
, int unit
, int subunit
, void *param
)
323 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
325 // skip disabled wl vifs
326 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
327 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
330 // set_mac(ifname, wl_nvname("macaddr", unit, subunit),
331 set_mac(ifname
, wl_nvname("hwaddr", unit
, subunit
), // AB multiSSID
332 2 + unit
+ ((subunit
> 0) ? ((unit
+ 1) * 0x10 + subunit
) : 0));
339 char *lan_ifname
, *lan_ifnames
, *ifname
, *p
;
346 foreach_wif(1, NULL
, set_wlmac
);
348 for(br
=0 ; br
<4 ; br
++) {
349 char bridge
[2] = "0";
357 strcat(tmp
, "_ifname");
358 lan_ifname
= nvram_safe_get(tmp
);
359 // lan_ifname = nvram_safe_get("lan_ifname");
360 if (strncmp(lan_ifname
, "br", 2) == 0) {
363 strcat(tmp
, "_ifnames");
364 // if ((lan_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
365 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
367 while ((ifname
= strsep(&p
, " ")) != NULL
) {
368 while (*ifname
== ' ') ++ifname
;
369 if (*ifname
== 0) break;
371 unit
= -1; subunit
= -1;
373 // ignore disabled wl vifs
374 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
376 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
377 if (!nvram_get_int(nv
))
379 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
382 // get the instance number of the wl i/f
383 else if (wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
)))
386 is_client
|= wl_client(unit
, subunit
) && nvram_get_int(wl_nvname("radio", unit
, 0));
389 eval("wlconf", ifname
, "start"); /* start wl iface */
390 #endif // CONFIG_BCMWL5
396 else if (strcmp(lan_ifname
, "")) {
397 /* specific non-bridged lan iface */
398 eval("wlconf", lan_ifname
, "start");
400 #endif // CONFIG_BCMWL5
403 killall("wldist", SIGTERM
);
407 xstart("radio", "join");
411 void enable_ipv6(int enable
)
414 struct dirent
*dirent
;
417 if ((dir
= opendir("/proc/sys/net/ipv6/conf")) != NULL
) {
418 while ((dirent
= readdir(dir
)) != NULL
) {
419 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", dirent
->d_name
);
420 f_write_string(s
, enable
? "0" : "1", 0, 0);
426 void accept_ra(const char *ifname
)
430 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/accept_ra", ifname
);
431 f_write_string(s
, "2", 0, 0);
433 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/forwarding", ifname
);
434 f_write_string(s
, "2", 0, 0);
440 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
444 char *lan_ifnames
, *ifname
, *p
;
447 int unit
, subunit
, sta
;
454 foreach_wif(1, NULL
, set_wlmac
);
457 enable_ipv6(ipv6_enabled());
460 if ((sfd
= socket(AF_INET
, SOCK_RAW
, IPPROTO_RAW
)) < 0) return;
461 for(br
=0 ; br
<4 ; br
++) {
462 char bridge
[2] = "0";
468 // lan_ifname = strdup(nvram_safe_get("lan_ifname"));
471 strcat(tmp
, "_ifname");
472 lan_ifname
= strdup(nvram_safe_get(tmp
));
474 if (strncmp(lan_ifname
, "br", 2) == 0) {
475 _dprintf("%s: setting up the bridge %s\n", __FUNCTION__
, lan_ifname
);
477 eval("brctl", "addbr", lan_ifname
);
478 eval("brctl", "setfd", lan_ifname
, "0");
482 eval("brctl", "stp", lan_ifname
, nvram_safe_get(tmp
));
485 if (nvram_get_int("emf_enable")) {
486 eval("emf", "add", "bridge", lan_ifname
);
487 eval("igs", "add", "bridge", lan_ifname
);
493 strcat(tmp
, "_ipaddr");
494 inet_aton(nvram_safe_get(tmp
), (struct in_addr
*)&ip
);
501 strcat(tmp
, "_ifnames");
502 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
504 while ((ifname
= strsep(&p
, " ")) != NULL
) {
505 while (*ifname
== ' ') ++ifname
;
506 if (*ifname
== 0) break;
508 unit
= -1; subunit
= -1;
510 // ignore disabled wl vifs
511 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
514 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
515 if (!nvram_get_int(nv
))
517 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
521 wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
));
523 // bring up interface
524 if (ifconfig(ifname
, IFUP
|IFF_ALLMULTI
, NULL
, NULL
) != 0) continue;
526 // set the logical bridge address to that of the first interface
527 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
529 (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0 &&
530 memcmp(ifr
.ifr_hwaddr
.sa_data
, "\0\0\0\0\0\0", ETHER_ADDR_LEN
) == 0)) {
531 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
532 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0) {
533 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
534 ifr
.ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
535 _dprintf("%s: setting MAC of %s bridge to %s\n", __FUNCTION__
,
536 ifr
.ifr_name
, ether_etoa(ifr
.ifr_hwaddr
.sa_data
, eabuf
));
537 ioctl(sfd
, SIOCSIFHWADDR
, &ifr
);
542 if (wlconf(ifname
, unit
, subunit
) == 0) {
543 const char *mode
= nvram_safe_get(wl_nvname("mode", unit
, subunit
));
545 if (strcmp(mode
, "wet") == 0) {
546 // Enable host DHCP relay
547 if (nvram_get_int("dhcp_relay")) {
548 wl_iovar_set(ifname
, "wet_host_mac", ifr
.ifr_hwaddr
.sa_data
, ETHER_ADDR_LEN
);
549 wl_iovar_setint(ifname
, "wet_host_ipv4", ip
);
553 sta
|= (strcmp(mode
, "sta") == 0);
554 if ((strcmp(mode
, "ap") != 0) && (strcmp(mode
, "wet") != 0)) continue;
556 eval("brctl", "addif", lan_ifname
, ifname
);
558 if (nvram_get_int("emf_enable"))
559 eval("emf", "add", "iface", lan_ifname
, ifname
);
563 if ((nvram_get_int("wan_islan")) && (br
==0) &&
564 ((get_wan_proto() == WP_DISABLED
) || (sta
))) {
565 ifname
= nvram_get("wan_ifnameX");
566 if (ifconfig(ifname
, IFUP
, NULL
, NULL
) == 0)
567 eval("brctl", "addif", lan_ifname
, ifname
);
573 // --- this shouldn't happen ---
574 else if (*lan_ifname
) {
575 ifconfig(lan_ifname
, IFUP
, NULL
, NULL
);
576 wlconf(lan_ifname
, -1, -1);
584 // Get current LAN hardware address
585 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
588 strcat(tmp
, "_hwaddr");
589 // if (ioctl(sfd, SIOCGIFHWADDR, &ifr) == 0) nvram_set("lan_hwaddr", ether_etoa(ifr.ifr_hwaddr.sa_data, eabuf));
590 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0) nvram_set(tmp
, ether_etoa(ifr
.ifr_hwaddr
.sa_data
, eabuf
));
592 // Set initial QoS mode for LAN ports
593 set_et_qos_mode(sfd
);
597 // bring up and configure LAN interface
600 strcat(tmp
, "_ipaddr");
603 strcat(tmp2
, "_netmask");
604 ifconfig(lan_ifname
, IFUP
, nvram_safe_get(tmp
), nvram_safe_get(tmp2
));
610 set_lan_hostname(nvram_safe_get("wan_hostname"));
612 if ((get_wan_proto() == WP_DISABLED
) && (br
==0)) {
613 char *gateway
= nvram_safe_get("lan_gateway") ;
614 if ((*gateway
) && (strcmp(gateway
, "0.0.0.0") != 0)) {
616 while ((route_add(lan_ifname
, 0, "0.0.0.0", gateway
, "0.0.0.0") != 0) && (tries
-- > 0)) sleep(1);
617 _dprintf("%s: add gateway=%s tries=%d\n", __FUNCTION__
, gateway
, tries
);
626 if (nvram_get_int("emf_enable")) start_emf(lan_ifname
);
631 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
636 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
639 char *lan_ifnames
, *p
, *ifname
;
643 for(br
=0 ; br
<4 ; br
++) {
644 char bridge
[2] = "0";
652 strcat(tmp
, "_ifname");
653 lan_ifname
= nvram_safe_get(tmp
);
654 ifconfig(lan_ifname
, 0, NULL
, NULL
);
660 if (strncmp(lan_ifname
, "br", 2) == 0) {
662 stop_emf(lan_ifname
);
666 strcat(tmp
, "_ifnames");
667 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
669 while ((ifname
= strsep(&p
, " ")) != NULL
) {
670 while (*ifname
== ' ') ++ifname
;
671 if (*ifname
== 0) break;
672 eval("wlconf", ifname
, "down");
673 ifconfig(ifname
, 0, NULL
, NULL
);
674 eval("brctl", "delif", lan_ifname
, ifname
);
678 eval("brctl", "delbr", lan_ifname
);
680 else if (*lan_ifname
) {
681 eval("wlconf", lan_ifname
, "down");
684 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
688 void do_static_routes(int add
)
692 char *dest
, *mask
, *gateway
, *metric
, *ifname
;
695 if ((buf
= strdup(nvram_safe_get(add
? "routes_static" : "routes_static_saved"))) == NULL
) return;
696 if (add
) nvram_set("routes_static_saved", buf
);
697 else nvram_unset("routes_static_saved");
699 while ((q
= strsep(&p
, ">")) != NULL
) {
700 if (vstrsep(q
, "<", &dest
, &gateway
, &mask
, &metric
, &ifname
) != 5) continue;
701 // ifname = nvram_safe_get((*ifname == 'L') ? "lan_ifname" :
702 // ((*ifname == 'W') ? "wan_iface" : "wan_ifname"));
703 ifname
= nvram_safe_get(((strcmp(ifname
,"LAN")==0) ? "lan_ifname" :
704 ((strcmp(ifname
,"LAN1")==0) ? "lan1_ifname" :
705 ((strcmp(ifname
,"LAN2")==0) ? "lan2_ifname" :
706 ((strcmp(ifname
,"LAN3")==0) ? "lan3_ifname" :
707 ((*ifname
== 'W') ? "wan_iface" : "wan_ifname"))))));
709 for (r
= 3; r
>= 0; --r
) {
710 if (route_add(ifname
, atoi(metric
), dest
, gateway
, mask
) == 0) break;
715 route_del(ifname
, atoi(metric
), dest
, gateway
, mask
);
721 void hotplug_net(void)
723 char *interface
, *action
;
726 if (((interface
= getenv("INTERFACE")) == NULL
) || ((action
= getenv("ACTION")) == NULL
)) return;
728 _dprintf("hotplug net INTERFACE=%s ACTION=%s\n", interface
, action
);
730 if ((strncmp(interface
, "wds", 3) == 0) &&
731 (strcmp(action
, "register") == 0 || strcmp(action
, "add") == 0)) {
732 ifconfig(interface
, IFUP
, NULL
, NULL
);
733 lan_ifname
= nvram_safe_get("lan_ifname");
735 if (nvram_get_int("emf_enable")) {
736 eval("emf", "add", "iface", lan_ifname
, interface
);
737 emf_mfdb_update(lan_ifname
, interface
, 1);
738 emf_uffp_update(lan_ifname
, interface
, 1);
739 emf_rtport_update(lan_ifname
, interface
, 1);
742 if (strncmp(lan_ifname
, "br", 2) == 0) {
743 eval("brctl", "addif", lan_ifname
, interface
);
744 notify_nas(interface
);
750 static int is_same_addr(struct ether_addr
*addr1
, struct ether_addr
*addr2
)
753 for (i
= 0; i
< 6; i
++) {
754 if (addr1
->octet
[i
] != addr2
->octet
[i
])
760 #define WL_MAX_ASSOC 128
761 static int check_wl_client(char *ifname
, int unit
, int subunit
)
763 struct ether_addr bssid
;
765 char buf
[WLC_IOCTL_MAXLEN
];
766 struct maclist
*mlist
;
768 int associated
, authorized
;
770 *(uint32
*)buf
= WLC_IOCTL_MAXLEN
;
771 if (wl_ioctl(ifname
, WLC_GET_BSSID
, &bssid
, ETHER_ADDR_LEN
) < 0 ||
772 wl_ioctl(ifname
, WLC_GET_BSS_INFO
, buf
, WLC_IOCTL_MAXLEN
) < 0)
775 bi
= (wl_bss_info_t
*)(buf
+ 4);
776 if ((bi
->SSID_len
== 0) ||
777 (bi
->BSSID
.octet
[0] + bi
->BSSID
.octet
[1] + bi
->BSSID
.octet
[2] +
778 bi
->BSSID
.octet
[3] + bi
->BSSID
.octet
[4] + bi
->BSSID
.octet
[5] == 0))
782 authorized
= strstr(nvram_safe_get(wl_nvname("akm", unit
, subunit
)), "psk") == 0;
784 mlsize
= sizeof(struct maclist
) + (WL_MAX_ASSOC
* sizeof(struct ether_addr
));
785 if ((mlist
= malloc(mlsize
)) != NULL
) {
786 mlist
->count
= WL_MAX_ASSOC
;
787 if (wl_ioctl(ifname
, WLC_GET_ASSOCLIST
, mlist
, mlsize
) == 0) {
788 for (i
= 0; i
< mlist
->count
; ++i
) {
789 if (is_same_addr(&mlist
->ea
[i
], &bi
->BSSID
)) {
796 if (associated
&& !authorized
) {
797 memset(mlist
, 0, mlsize
);
798 mlist
->count
= WL_MAX_ASSOC
;
799 strcpy((char*)mlist
, "autho_sta_list");
800 if (wl_ioctl(ifname
, WLC_GET_VAR
, mlist
, mlsize
) == 0) {
801 for (i
= 0; i
< mlist
->count
; ++i
) {
802 if (is_same_addr(&mlist
->ea
[i
], &bi
->BSSID
)) {
812 return (associated
&& authorized
);
815 #define STACHECK_CONNECT 30
816 #define STACHECK_DISCONNECT 5
818 static int radio_join(int idx
, int unit
, int subunit
, void *param
)
824 int *unit_filter
= param
;
825 if (*unit_filter
>= 0 && *unit_filter
!= unit
) return 0;
827 if (!nvram_get_int(wl_nvname("radio", unit
, 0)) || !wl_client(unit
, subunit
)) return 0;
829 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
831 // skip disabled wl vifs
832 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
833 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
836 sprintf(f
, "/var/run/radio.%d.%d.pid", unit
, subunit
< 0 ? 0 : subunit
);
837 if (f_read_string(f
, s
, sizeof(s
)) > 0) {
838 if ((i
= atoi(s
)) > 1) {
845 sprintf(s
, "%d", getpid());
846 f_write(f
, s
, sizeof(s
), 0, 0644);
848 int stacheck_connect
= nvram_get_int("sta_chkint");
849 if (stacheck_connect
<= 0)
850 stacheck_connect
= STACHECK_CONNECT
;
853 while (get_radio(unit
) && wl_client(unit
, subunit
)) {
855 if (check_wl_client(ifname
, unit
, subunit
)) {
856 stacheck
= stacheck_connect
;
859 eval("wl", "-i", ifname
, "disassoc");
861 char *amode
, *sec
= nvram_safe_get(wl_nvname("akm", unit
, subunit
));
863 if (strstr(sec
, "psk2")) amode
= "wpa2psk";
864 else if (strstr(sec
, "psk")) amode
= "wpapsk";
865 else if (strstr(sec
, "wpa2")) amode
= "wpa2";
866 else if (strstr(sec
, "wpa")) amode
= "wpa";
867 else if (nvram_get_int(wl_nvname("auth", unit
, subunit
))) amode
= "shared";
870 eval("wl", "-i", ifname
, "join", nvram_safe_get(wl_nvname("ssid", unit
, subunit
)),
871 "imode", "bss", "amode", amode
);
873 eval("wl", "-i", ifname
, "join", nvram_safe_get(wl_nvname("ssid", unit
, subunit
)));
875 stacheck
= STACHECK_DISCONNECT
;
891 static int radio_toggle(int idx
, int unit
, int subunit
, void *param
)
893 if (!nvram_get_int(wl_nvname("radio", unit
, 0))) return 0;
897 if (*op
== RADIO_TOGGLE
) {
898 *op
= get_radio(unit
) ? RADIO_OFF
: RADIO_ON
;
901 set_radio(*op
, unit
);
905 int radio_main(int argc
, char *argv
[])
912 usage_exit(argv
[0], "on|off|toggle|join [N]\n");
914 unit
= (argc
== 3) ? atoi(argv
[2]) : -1;
916 if (strcmp(argv
[1], "toggle") == 0)
918 else if (strcmp(argv
[1], "off") == 0)
920 else if (strcmp(argv
[1], "on") == 0)
922 else if (strcmp(argv
[1], "join") == 0)
928 op
= radio_toggle(0, unit
, 0, &op
);
930 op
= foreach_wif(0, &op
, radio_toggle
);
937 foreach_wif(1, &unit
, radio_join
);
942 int wdist_main(int argc, char *argv[])
951 if (wl_ioctl(nvram_safe_get("wl_ifname"), 101, &r, sizeof(r)) == 0) {
954 else v = (v - (9 + 1)) * 150;
955 printf("Current: %d-%dm (0x%02x)\n\n", v + (v ? 1 : 0), v + 150, r.val);
957 usage_exit(argv[0], "<meters>");
959 if ((n = atoi(argv[1])) <= 0) setup_wldistance();
960 else set_wldistance(n);
965 static int get_wldist(int idx
, int unit
, int subunit
, void *param
)
969 char *p
= nvram_safe_get(wl_nvname("distance", unit
, 0));
970 if ((*p
== 0) || ((n
= atoi(p
)) < 0)) return 0;
972 return (9 + (n
/ 150) + ((n
% 150) ? 1 : 0));
975 static int wldist(int idx
, int unit
, int subunit
, void *param
)
982 n
= get_wldist(idx
, unit
, subunit
, param
);
984 s
= 0x10 | (n
<< 16);
985 p
= nvram_safe_get(wl_nvname("ifname", unit
, 0));
986 wl_ioctl(p
, 197, &s
, sizeof(s
));
991 wl_ioctl(p
, 102, &r
, sizeof(r
));
997 int wldist_main(int argc
, char *argv
[])
1000 if (foreach_wif(0, NULL
, get_wldist
) == 0) return 0;
1003 foreach_wif(0, NULL
, wldist
);