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 void restart_wl(void);
74 void stop_lan_wl(void);
75 void start_lan_wl(void);
77 static void set_lan_hostname(const char *wan_hostname
)
82 nvram_set("lan_hostname", wan_hostname
);
83 if ((wan_hostname
== NULL
) || (*wan_hostname
== 0)) {
84 /* derive from et0 mac address */
85 s
= nvram_get("et0macaddr");
86 if (s
&& strlen(s
) >= 17) {
88 sprintf(hostname
, "RT-%c%c%c%c%c%c%c%c%c%c%c%c",
89 s
[0], s
[1], s
[3], s
[4], s
[6], s
[7],
90 s
[9], s
[10], s
[12], s
[13], s
[15], s
[16]);
92 if ((f
= fopen("/proc/sys/kernel/hostname", "w"))) {
96 nvram_set("lan_hostname", hostname
);
100 if ((f
= fopen("/etc/hosts", "w"))) {
101 fprintf(f
, "127.0.0.1 localhost\n");
102 if ((s
= nvram_get("lan_ipaddr")) && (*s
))
103 fprintf(f
, "%s %s %s-lan\n", s
, nvram_safe_get("lan_hostname"), nvram_safe_get("lan_hostname"));
104 if ((s
= nvram_get("lan1_ipaddr")) && (*s
) && (strcmp(s
,"") != 0))
105 fprintf(f
, "%s %s-lan1\n", s
, nvram_safe_get("lan_hostname"));
106 if ((s
= nvram_get("lan2_ipaddr")) && (*s
) && (strcmp(s
,"") != 0))
107 fprintf(f
, "%s %s-lan2\n", s
, nvram_safe_get("lan_hostname"));
108 if ((s
= nvram_get("lan3_ipaddr")) && (*s
) && (strcmp(s
,"") != 0))
109 fprintf(f
, "%s %s-lan3\n", s
, nvram_safe_get("lan_hostname"));
111 if (ipv6_enabled()) {
112 fprintf(f
, "::1 localhost\n");
113 s
= ipv6_router_address(NULL
);
114 if (*s
) fprintf(f
, "%s %s\n", s
, nvram_safe_get("lan_hostname"));
121 void set_host_domain_name(void)
125 s
= nvram_safe_get("wan_hostname");
126 sethostname(s
, strlen(s
));
129 s
= nvram_get("wan_domain");
130 if ((s
== NULL
) || (*s
== 0)) s
= nvram_safe_get("wan_get_domain");
131 setdomainname(s
, strlen(s
));
134 static int wlconf(char *ifname
, int unit
, int subunit
)
139 if (/* !wl_probe(ifname) && */ unit
>= 0) {
140 // validate nvram settings for wireless i/f
141 snprintf(wl
, sizeof(wl
), "--wl%d", unit
);
142 eval("nvram", "validate", wl
);
145 r
= eval("wlconf", ifname
, "up");
147 if (unit
>= 0 && subunit
<= 0) {
148 // setup primary wl interface
149 nvram_set("rrules_radio", "-1");
151 eval("wl", "-i", ifname
, "antdiv", nvram_safe_get(wl_nvname("antdiv", unit
, 0)));
152 eval("wl", "-i", ifname
, "txant", nvram_safe_get(wl_nvname("txant", unit
, 0)));
153 eval("wl", "-i", ifname
, "txpwr1", "-o", "-m", nvram_get_int(wl_nvname("txpwr", unit
, 0)) ? nvram_safe_get(wl_nvname("txpwr", unit
, 0)) : "-1");
154 eval("wl", "-i", ifname
, "interference", nvram_safe_get(wl_nvname("mitigation", unit
, 0)));
157 if (wl_client(unit
, subunit
)) {
158 if (nvram_match(wl_nvname("mode", unit
, subunit
), "wet")) {
159 ifconfig(ifname
, IFUP
|IFF_ALLMULTI
, NULL
, NULL
);
161 if (nvram_get_int(wl_nvname("radio", unit
, 0))) {
162 snprintf(wl
, sizeof(wl
), "%d", unit
);
163 xstart("radio", "join", wl
);
170 // -----------------------------------------------------------------------------
173 static void emf_mfdb_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
175 char word
[256], *next
;
178 /* Add/Delete MFDB entries corresponding to new interface */
179 foreach (word
, nvram_safe_get("emf_entry"), next
) {
181 mgrp
= strsep(&ifname
, ":");
183 if ((mgrp
== NULL
) || (ifname
== NULL
)) continue;
185 /* Add/Delete MFDB entry using the group addr and interface */
186 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
187 eval("emf", ((add
) ? "add" : "del"), "mfdb", lan_ifname
, mgrp
, ifname
);
192 static void emf_uffp_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
194 char word
[256], *next
;
197 /* Add/Delete UFFP entries corresponding to new interface */
198 foreach (word
, nvram_safe_get("emf_uffp_entry"), next
) {
201 if (ifname
== NULL
) continue;
203 /* Add/Delete UFFP entry for the interface */
204 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
205 eval("emf", ((add
) ? "add" : "del"), "uffp", lan_ifname
, ifname
);
210 static void emf_rtport_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
212 char word
[256], *next
;
215 /* Add/Delete RTPORT entries corresponding to new interface */
216 foreach (word
, nvram_safe_get("emf_rtport_entry"), next
) {
219 if (ifname
== NULL
) continue;
221 /* Add/Delete RTPORT entry for the interface */
222 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
223 eval("emf", ((add
) ? "add" : "del"), "rtport", lan_ifname
, ifname
);
228 static void start_emf(char *lan_ifname
)
231 eval("emf", "start", lan_ifname
);
233 /* Add the static MFDB entries */
234 emf_mfdb_update(lan_ifname
, NULL
, 1);
236 /* Add the UFFP entries */
237 emf_uffp_update(lan_ifname
, NULL
, 1);
239 /* Add the RTPORT entries */
240 emf_rtport_update(lan_ifname
, NULL
, 1);
243 static void stop_emf(char *lan_ifname
)
245 eval("emf", "stop", lan_ifname
);
246 eval("igs", "del", "bridge", lan_ifname
);
247 eval("emf", "del", "bridge", lan_ifname
);
251 // -----------------------------------------------------------------------------
253 /* Set initial QoS mode for all et interfaces that are up. */
254 void set_et_qos_mode(int sfd
)
259 struct ethtool_drvinfo info
;
261 qos
= (strcmp(nvram_safe_get("wl_wme"), "off") != 0);
262 for (i
= 1; i
<= DEV_NUMIFS
; i
++) {
264 if (ioctl(sfd
, SIOCGIFNAME
, &ifr
)) continue;
265 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
)) continue;
266 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) continue;
268 if (ioctl(sfd
, SIOCGIFFLAGS
, &ifr
)) continue;
269 /* if up (wan may not be up yet at this point) */
270 if (ifr
.ifr_flags
& IFF_UP
) {
271 ifrdata
= ifr
.ifr_data
;
272 memset(&info
, 0, sizeof(info
));
273 info
.cmd
= ETHTOOL_GDRVINFO
;
274 ifr
.ifr_data
= (caddr_t
)&info
;
275 if (ioctl(sfd
, SIOCETHTOOL
, &ifr
) >= 0) {
276 /* Set QoS for et & bcm57xx devices */
278 if (!strncmp(info
.driver
, "et", 2) ||
279 !strncmp(info
.driver
, "bcm57", 5)) {
280 ifr
.ifr_data
= (caddr_t
)&qos
;
281 ioctl(sfd
, SIOCSETCQOS
, &ifr
);
285 ifr
.ifr_data
= ifrdata
;
290 static void check_afterburner(void)
294 if (nvram_match("wl_afterburner", "off")) return;
295 if ((p
= nvram_get("boardflags")) == NULL
) return;
297 if (strcmp(p
, "0x0118") == 0) { // G 2.2, 3.0, 3.1
300 else if (strcmp(p
, "0x0188") == 0) { // G 2.0
303 else if (strcmp(p
, "0x2558") == 0) { // G 4.0, GL 1.0, 1.1
310 nvram_set("boardflags", p
);
312 if (!nvram_match("debug_abrst", "0")) {
325 bf = strtoul(p, &p, 0);
326 if ((*p == 0) && ((bf & BFL_AFTERBURNER) == 0)) {
327 sprintf(s, "0x%04lX", bf | BFL_AFTERBURNER);
328 nvram_set("boardflags", s);
343 static int set_wlmac(int idx
, int unit
, int subunit
, void *param
)
347 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
349 // skip disabled wl vifs
350 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
351 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
354 if (strcmp(nvram_safe_get(wl_nvname("hwaddr", unit
, subunit
)), "") == 0) {
355 // set_mac(ifname, wl_nvname("macaddr", unit, subunit),
356 set_mac(ifname
, wl_nvname("hwaddr", unit
, subunit
), // AB multiSSID
357 2 + unit
+ ((subunit
> 0) ? ((unit
+ 1) * 0x10 + subunit
) : 0));
359 set_mac(ifname
, wl_nvname("hwaddr", unit
, subunit
), 0);
364 void stop_lan_wl(void)
373 eval("ebtables", "-F");
378 for(br
=0 ; br
<4 ; br
++) {
379 char bridge
[2] = "0";
387 strcat(tmp
, "_ifname");
388 lan_ifname
= nvram_safe_get(tmp
);
392 strcat(tmp
, "_ifnames");
393 if ((wl_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
395 while ((ifname
= strsep(&p
, " ")) != NULL
) {
396 while (*ifname
== ' ') ++ifname
;
397 if (*ifname
== 0) continue;
399 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
400 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
403 else if (wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
)))
406 eval("wlconf", ifname
, "down");
408 eval("brctl", "delif", lan_ifname
, ifname
);
409 ifconfig(ifname
, 0, NULL
, NULL
);
416 void start_lan_wl(void)
422 char *wl_ifnames
, *ifname
, *p
;
424 int unit
, subunit
, sta
;
430 foreach_wif(0, NULL
, set_wlmac
);
432 foreach_wif(1, NULL
, set_wlmac
);
435 for(br
=0 ; br
<4 ; br
++) {
436 char bridge
[2] = "0";
444 strcat(tmp
, "_ifname");
445 lan_ifname
= nvram_safe_get(tmp
);
447 if (strncmp(lan_ifname
, "br", 2) == 0) {
450 strcat(tmp
, "_ipaddr");
451 inet_aton(nvram_safe_get(tmp
), (struct in_addr
*)&ip
);
455 strcat(tmp
, "_ifnames");
459 if ((wl_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
461 while ((ifname
= strsep(&p
, " ")) != NULL
) {
462 while (*ifname
== ' ') ++ifname
;
463 if (*ifname
== 0) continue;
465 unit
= -1; subunit
= -1;
467 // ignore disabled wl vifs
469 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
472 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
473 if (!nvram_get_int(nv
))
476 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
478 set_wlmac(0, unit
, subunit
, NULL
);
481 wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
));
484 // bring up interface
485 if (ifconfig(ifname
, IFUP
, NULL
, NULL
) != 0) continue;
488 if (wlconf(ifname
, unit
, subunit
) == 0) {
489 const char *mode
= nvram_safe_get(wl_nvname("mode", unit
, subunit
));
491 if (strcmp(mode
, "wet") == 0) {
492 // Enable host DHCP relay
493 if (nvram_get_int("dhcp_relay")) {
494 wl_iovar_set(ifname
, "wet_host_mac", ifr
.ifr_hwaddr
.sa_data
, ETHER_ADDR_LEN
);
495 wl_iovar_setint(ifname
, "wet_host_ipv4", ip
);
499 sta
|= (strcmp(mode
, "sta") == 0);
500 if ((strcmp(mode
, "ap") != 0) && (strcmp(mode
, "wet") != 0)) continue;
503 eval("brctl", "addif", lan_ifname
, ifname
);
519 void start_wireless()
529 void restart_wl(void)
531 char *lan_ifnames
, *ifname
, *p
;
538 for(br
=0 ; br
<4 ; br
++) {
539 char bridge
[2] = "0";
547 strcat(tmp
, "_ifnames");
548 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
550 while ((ifname
= strsep(&p
, " ")) != NULL
) {
551 while (*ifname
== ' ') ++ifname
;
552 if (*ifname
== 0) continue;
554 unit
= -1; subunit
= -1;
556 // ignore disabled wl vifs
557 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
559 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
560 if (!nvram_get_int(nv
))
562 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
565 // get the instance number of the wl i/f
566 else if (wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
)))
569 is_client
|= wl_client(unit
, subunit
) && nvram_get_int(wl_nvname("radio", unit
, 0));
572 eval("wlconf", ifname
, "start"); /* start wl iface */
573 #endif // CONFIG_BCMWL5
579 killall("wldist", SIGTERM
);
583 xstart("radio", "join");
585 if (get_model() == MODEL_WS880
) {
586 if (nvram_match("wl0_radio", "1") || nvram_match("wl1_radio", "1"))
587 led(LED_WLAN
, LED_ON
);
589 led(LED_WLAN
, LED_OFF
);
594 static int disabled_wl(int idx
, int unit
, int subunit
, void *param
)
598 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
600 // skip disabled wl vifs
601 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
602 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
610 char *lan_ifname
, *lan_ifnames
, *ifname
, *p
;
618 // HACK: When a virtual SSID is disabled, it requires two initialisation
619 if (foreach_wif(1, NULL
, disabled_wl
))
627 for(br
=0 ; br
<4 ; br
++) {
628 char bridge
[2] = "0";
636 strcat(tmp
, "_ifname");
637 lan_ifname
= nvram_safe_get(tmp
);
638 if (strncmp(lan_ifname
, "br", 2) == 0) {
641 strcat(tmp
, "_ifnames");
642 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
644 while ((ifname
= strsep(&p
, " ")) != NULL
) {
645 while (*ifname
== ' ') ++ifname
;
646 if (*ifname
== 0) continue;
648 unit
= -1; subunit
= -1;
650 // ignore disabled wl vifs
651 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
653 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
654 if (!nvram_get_int(nv
))
656 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
659 // get the instance number of the wl i/f
660 else if (wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
)))
663 is_client
|= wl_client(unit
, subunit
) && nvram_get_int(wl_nvname("radio", unit
, 0));
666 eval("wlconf", ifname
, "start"); /* start wl iface */
667 // Enable LED if wireless interface is enabled, and turn on blink (traffic "control" of LED) if enabled
668 if (nvram_get_int(wl_nvname("radio", unit
, 0))) {
670 led(LED_WLAN
, LED_ON
);
671 if (nvram_get_int("blink_wl"))
672 eval("blink", ifname
, "wlan", "20", "8192");
676 if (nvram_get_int("blink_wl"))
677 eval("blink", ifname
, "5g", "20", "8192");
680 #endif // CONFIG_BCMWL5
686 else if (strcmp(lan_ifname
, "")) {
687 /* specific non-bridged lan iface */
688 eval("wlconf", lan_ifname
, "start");
690 #endif // CONFIG_BCMWL5
693 killall("wldist", SIGTERM
);
697 xstart("radio", "join");
699 if (get_model() == MODEL_WS880
) {
700 if (nvram_match("wl0_radio", "1") || nvram_match("wl1_radio", "1"))
701 led(LED_WLAN
, LED_ON
);
703 led(LED_WLAN
, LED_OFF
);
708 void enable_ipv6(int enable
)
711 struct dirent
*dirent
;
714 if ((dir
= opendir("/proc/sys/net/ipv6/conf")) != NULL
) {
715 while ((dirent
= readdir(dir
)) != NULL
) {
716 if (strcmp("vlan1", dirent
->d_name
) &&
717 strcmp("eth0", dirent
->d_name
) &&
718 strcmp("all", dirent
->d_name
) &&
719 strcmp("eth1", dirent
->d_name
))
722 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", dirent
->d_name
);
723 f_write_string(s
, enable
? "0" : "1", 0, 0);
730 void accept_ra(const char *ifname
)
734 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/accept_ra", ifname
);
735 f_write_string(s
, "2", 0, 0);
737 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/forwarding", ifname
);
738 f_write_string(s
, "2", 0, 0);
744 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
748 char *lan_ifnames
, *ifname
, *p
;
751 int unit
, subunit
, sta
;
764 foreach_wif(0, NULL
, set_wlmac
);
766 foreach_wif(1, NULL
, set_wlmac
);
770 enable_ipv6(ipv6_enabled()); //tell Kernel to disable/enable IPv6 for most interfaces
772 vlan0tag
= nvram_get_int("vlan0tag");
774 if ((sfd
= socket(AF_INET
, SOCK_RAW
, IPPROTO_RAW
)) < 0) return;
775 for(br
=0 ; br
<4 ; br
++) {
776 char bridge
[2] = "0";
784 strcat(tmp
, "_ifname");
785 lan_ifname
= strdup(nvram_safe_get(tmp
));
787 if (strncmp(lan_ifname
, "br", 2) == 0) {
788 _dprintf("%s: setting up the bridge %s\n", __FUNCTION__
, lan_ifname
);
790 eval("brctl", "addbr", lan_ifname
);
791 eval("brctl", "setfd", lan_ifname
, "0");
795 eval("brctl", "stp", lan_ifname
, nvram_safe_get(tmp
));
798 if (nvram_get_int("emf_enable")) {
799 eval("emf", "add", "bridge", lan_ifname
);
800 eval("igs", "add", "bridge", lan_ifname
);
806 strcat(tmp
, "_ipaddr");
807 inet_aton(nvram_safe_get(tmp
), (struct in_addr
*)&ip
);
814 strcat(tmp
, "_ifnames");
815 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
817 while ((iftmp
= strsep(&p
, " ")) != NULL
) {
818 while (*iftmp
== ' ') ++iftmp
;
819 if (*iftmp
== 0) continue;
822 unit
= -1; subunit
= -1;
824 // ignore disabled wl vifs
825 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
827 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
828 if (!nvram_get_int(nv
))
830 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
833 set_wlmac(0, unit
, subunit
, NULL
);
837 wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
));
840 if (strncmp(ifname
, "vlan", 4) == 0) {
841 if (sscanf(ifname
, "vlan%d", &vid
) == 1) {
842 snprintf(tmp
, sizeof(tmp
), "vlan%dvid", vid
);
843 vid_map
= nvram_get_int(tmp
);
844 if ((vid_map
< 1) || (vid_map
> 4094)) vid_map
= vlan0tag
| vid
;
845 snprintf(tmp
, sizeof(tmp
), "vlan%d", vid_map
);
850 // bring up interface
851 if (ifconfig(ifname
, IFUP
|IFF_ALLMULTI
, NULL
, NULL
) != 0) continue;
853 // set the logical bridge address to that of the first interface
854 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
856 (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0 &&
857 memcmp(ifr
.ifr_hwaddr
.sa_data
, "\0\0\0\0\0\0", ETHER_ADDR_LEN
) == 0)) {
858 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
859 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0) {
860 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
861 ifr
.ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
862 _dprintf("%s: setting MAC of %s bridge to %s\n", __FUNCTION__
,
863 ifr
.ifr_name
, ether_etoa(ifr
.ifr_hwaddr
.sa_data
, eabuf
));
864 ioctl(sfd
, SIOCSIFHWADDR
, &ifr
);
869 if (wlconf(ifname
, unit
, subunit
) == 0) {
870 const char *mode
= nvram_safe_get(wl_nvname("mode", unit
, subunit
));
872 if (strcmp(mode
, "wet") == 0) {
873 // Enable host DHCP relay
874 if (nvram_get_int("dhcp_relay")) {
875 wl_iovar_set(ifname
, "wet_host_mac", ifr
.ifr_hwaddr
.sa_data
, ETHER_ADDR_LEN
);
876 wl_iovar_setint(ifname
, "wet_host_ipv4", ip
);
880 sta
|= (strcmp(mode
, "sta") == 0);
881 if ((strcmp(mode
, "ap") != 0) && (strcmp(mode
, "wet") != 0)) continue;
883 eval("brctl", "addif", lan_ifname
, ifname
);
885 if (nvram_get_int("emf_enable"))
886 eval("emf", "add", "iface", lan_ifname
, ifname
);
890 if ((nvram_get_int("wan_islan")) && (br
==0) &&
891 ((get_wan_proto() == WP_DISABLED
) || (sta
))) {
892 ifname
= nvram_get("wan_ifnameX");
893 if (ifconfig(ifname
, IFUP
, NULL
, NULL
) == 0)
894 eval("brctl", "addif", lan_ifname
, ifname
);
900 // --- this shouldn't happen ---
901 else if (*lan_ifname
) {
902 ifconfig(lan_ifname
, IFUP
, NULL
, NULL
);
903 wlconf(lan_ifname
, -1, -1);
911 // Get current LAN hardware address
912 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
915 strcat(tmp
, "_hwaddr");
916 // if (ioctl(sfd, SIOCGIFHWADDR, &ifr) == 0) nvram_set("lan_hwaddr", ether_etoa(ifr.ifr_hwaddr.sa_data, eabuf));
917 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0) nvram_set(tmp
, ether_etoa(ifr
.ifr_hwaddr
.sa_data
, eabuf
));
919 // Set initial QoS mode for LAN ports
920 set_et_qos_mode(sfd
);
924 // bring up and configure LAN interface
927 strcat(tmp
, "_ipaddr");
930 strcat(tmp2
, "_netmask");
931 ifconfig(lan_ifname
, IFUP
, nvram_safe_get(tmp
), nvram_safe_get(tmp2
));
937 set_lan_hostname(nvram_safe_get("wan_hostname"));
939 if ((get_wan_proto() == WP_DISABLED
) && (br
==0)) {
940 char *gateway
= nvram_safe_get("lan_gateway") ;
941 if ((*gateway
) && (strcmp(gateway
, "0.0.0.0") != 0)) {
943 while ((route_add(lan_ifname
, 0, "0.0.0.0", gateway
, "0.0.0.0") != 0) && (tries
-- > 0)) sleep(1);
944 _dprintf("%s: add gateway=%s tries=%d\n", __FUNCTION__
, gateway
, tries
);
953 if (nvram_get_int("emf_enable")) start_emf(lan_ifname
);
958 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
963 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
966 char *lan_ifnames
, *p
, *ifname
;
969 int vlan0tag
, vid
, vid_map
;
972 vlan0tag
= nvram_get_int("vlan0tag");
974 for(br
=0 ; br
<4 ; br
++) {
975 char bridge
[2] = "0";
983 strcat(tmp
, "_ifname");
984 lan_ifname
= nvram_safe_get(tmp
);
985 ifconfig(lan_ifname
, 0, NULL
, NULL
);
991 if (strncmp(lan_ifname
, "br", 2) == 0) {
993 stop_emf(lan_ifname
);
997 strcat(tmp
, "_ifnames");
998 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
1000 while ((iftmp
= strsep(&p
, " ")) != NULL
) {
1001 while (*iftmp
== ' ') ++iftmp
;
1002 if (*iftmp
== 0) continue;
1005 if (strncmp(ifname
, "vlan", 4) == 0) {
1006 if (sscanf(ifname
, "vlan%d", &vid
) == 1) {
1007 snprintf(tmp
, sizeof(tmp
), "vlan%dvid", vid
);
1008 vid_map
= nvram_get_int(tmp
);
1009 if ((vid_map
< 1) || (vid_map
> 4094)) vid_map
= vlan0tag
| vid
;
1010 snprintf(tmp
, sizeof(tmp
), "vlan%d", vid_map
);
1014 eval("wlconf", ifname
, "down");
1015 ifconfig(ifname
, 0, NULL
, NULL
);
1016 eval("brctl", "delif", lan_ifname
, ifname
);
1020 eval("brctl", "delbr", lan_ifname
);
1022 else if (*lan_ifname
) {
1023 eval("wlconf", lan_ifname
, "down");
1026 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
1029 static int is_sta(int idx
, int unit
, int subunit
, void *param
)
1031 return (nvram_match(wl_nvname("mode", unit
, subunit
), "sta") && (nvram_match(wl_nvname("bss_enabled", unit
, subunit
), "1")));
1034 void do_static_routes(int add
)
1038 char *dest
, *mask
, *gateway
, *metric
, *ifname
;
1041 if ((buf
= strdup(nvram_safe_get(add
? "routes_static" : "routes_static_saved"))) == NULL
) return;
1042 if (add
) nvram_set("routes_static_saved", buf
);
1043 else nvram_unset("routes_static_saved");
1045 while ((q
= strsep(&p
, ">")) != NULL
) {
1046 if (vstrsep(q
, "<", &dest
, &gateway
, &mask
, &metric
, &ifname
) != 5) continue;
1047 ifname
= nvram_safe_get(((strcmp(ifname
,"LAN")==0) ? "lan_ifname" :
1048 ((strcmp(ifname
,"LAN1")==0) ? "lan1_ifname" :
1049 ((strcmp(ifname
,"LAN2")==0) ? "lan2_ifname" :
1050 ((strcmp(ifname
,"LAN3")==0) ? "lan3_ifname" :
1051 ((*ifname
== 'W') ? "wan_iface" : "wan_ifname"))))));
1053 for (r
= 3; r
>= 0; --r
) {
1054 if (route_add(ifname
, atoi(metric
), dest
, gateway
, mask
) == 0) break;
1059 route_del(ifname
, atoi(metric
), dest
, gateway
, mask
);
1065 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
1066 && (modem_ipaddr
= nvram_safe_get("modem_ipaddr")) && *modem_ipaddr
&& !nvram_match("modem_ipaddr","0.0.0.0")
1067 && (!foreach_wif(1, NULL
, is_sta
)) ) {
1069 char *end
= rindex(modem_ipaddr
,'.')+1;
1070 unsigned char c
= atoi(end
);
1071 char *iface
= nvram_safe_get("wan_ifname");
1073 sprintf(ip
, "%.*s%hhu", end
-modem_ipaddr
, modem_ipaddr
, (unsigned char)(c
^1^((c
&2)^((c
&1)<<1))) );
1074 eval("ip", "addr", add
?"add":"del", ip
, "peer", modem_ipaddr
, "dev", iface
);
1079 void hotplug_net(void)
1081 char *interface
, *action
;
1084 if (((interface
= getenv("INTERFACE")) == NULL
) || ((action
= getenv("ACTION")) == NULL
)) return;
1086 _dprintf("hotplug net INTERFACE=%s ACTION=%s\n", interface
, action
);
1088 if ((strncmp(interface
, "wds", 3) == 0) &&
1089 (strcmp(action
, "register") == 0 || strcmp(action
, "add") == 0)) {
1090 ifconfig(interface
, IFUP
, NULL
, NULL
);
1091 lan_ifname
= nvram_safe_get("lan_ifname");
1093 if (nvram_get_int("emf_enable")) {
1094 eval("emf", "add", "iface", lan_ifname
, interface
);
1095 emf_mfdb_update(lan_ifname
, interface
, 1);
1096 emf_uffp_update(lan_ifname
, interface
, 1);
1097 emf_rtport_update(lan_ifname
, interface
, 1);
1100 if (strncmp(lan_ifname
, "br", 2) == 0) {
1101 eval("brctl", "addif", lan_ifname
, interface
);
1102 notify_nas(interface
);
1108 static int is_same_addr(struct ether_addr
*addr1
, struct ether_addr
*addr2
)
1111 for (i
= 0; i
< 6; i
++) {
1112 if (addr1
->octet
[i
] != addr2
->octet
[i
])
1118 #define WL_MAX_ASSOC 128
1119 static int check_wl_client(char *ifname
, int unit
, int subunit
)
1121 struct ether_addr bssid
;
1123 char buf
[WLC_IOCTL_MAXLEN
];
1124 struct maclist
*mlist
;
1126 int associated
, authorized
;
1128 *(uint32
*)buf
= WLC_IOCTL_MAXLEN
;
1129 if (wl_ioctl(ifname
, WLC_GET_BSSID
, &bssid
, ETHER_ADDR_LEN
) < 0 ||
1130 wl_ioctl(ifname
, WLC_GET_BSS_INFO
, buf
, WLC_IOCTL_MAXLEN
) < 0)
1133 bi
= (wl_bss_info_t
*)(buf
+ 4);
1134 if ((bi
->SSID_len
== 0) ||
1135 (bi
->BSSID
.octet
[0] + bi
->BSSID
.octet
[1] + bi
->BSSID
.octet
[2] +
1136 bi
->BSSID
.octet
[3] + bi
->BSSID
.octet
[4] + bi
->BSSID
.octet
[5] == 0))
1140 authorized
= strstr(nvram_safe_get(wl_nvname("akm", unit
, subunit
)), "psk") == 0;
1142 mlsize
= sizeof(struct maclist
) + (WL_MAX_ASSOC
* sizeof(struct ether_addr
));
1143 if ((mlist
= malloc(mlsize
)) != NULL
) {
1144 mlist
->count
= WL_MAX_ASSOC
;
1145 if (wl_ioctl(ifname
, WLC_GET_ASSOCLIST
, mlist
, mlsize
) == 0) {
1146 for (i
= 0; i
< mlist
->count
; ++i
) {
1147 if (is_same_addr(&mlist
->ea
[i
], &bi
->BSSID
)) {
1154 if (associated
&& !authorized
) {
1155 memset(mlist
, 0, mlsize
);
1156 mlist
->count
= WL_MAX_ASSOC
;
1157 strcpy((char*)mlist
, "autho_sta_list");
1158 if (wl_ioctl(ifname
, WLC_GET_VAR
, mlist
, mlsize
) == 0) {
1159 for (i
= 0; i
< mlist
->count
; ++i
) {
1160 if (is_same_addr(&mlist
->ea
[i
], &bi
->BSSID
)) {
1170 return (associated
&& authorized
);
1173 #define STACHECK_CONNECT 30
1174 #define STACHECK_DISCONNECT 5
1176 static int radio_join(int idx
, int unit
, int subunit
, void *param
)
1182 int *unit_filter
= param
;
1183 if (*unit_filter
>= 0 && *unit_filter
!= unit
) return 0;
1185 if (!nvram_get_int(wl_nvname("radio", unit
, 0)) || !wl_client(unit
, subunit
)) return 0;
1187 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
1189 // skip disabled wl vifs
1190 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
1191 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
1194 sprintf(f
, "/var/run/radio.%d.%d.pid", unit
, subunit
< 0 ? 0 : subunit
);
1195 if (f_read_string(f
, s
, sizeof(s
)) > 0) {
1196 if ((i
= atoi(s
)) > 1) {
1203 sprintf(s
, "%d", getpid());
1204 f_write(f
, s
, sizeof(s
), 0, 0644);
1206 int stacheck_connect
= nvram_get_int("sta_chkint");
1207 if (stacheck_connect
<= 0)
1208 stacheck_connect
= STACHECK_CONNECT
;
1211 while (get_radio(unit
) && wl_client(unit
, subunit
)) {
1213 if (check_wl_client(ifname
, unit
, subunit
)) {
1214 stacheck
= stacheck_connect
;
1217 eval("wl", "-i", ifname
, "disassoc");
1218 #ifdef CONFIG_BCMWL5
1219 char *amode
, *sec
= nvram_safe_get(wl_nvname("akm", unit
, subunit
));
1221 if (strstr(sec
, "psk2")) amode
= "wpa2psk";
1222 else if (strstr(sec
, "psk")) amode
= "wpapsk";
1223 else if (strstr(sec
, "wpa2")) amode
= "wpa2";
1224 else if (strstr(sec
, "wpa")) amode
= "wpa";
1225 else if (nvram_get_int(wl_nvname("auth", unit
, subunit
))) amode
= "shared";
1226 else amode
= "open";
1228 eval("wl", "-i", ifname
, "join", nvram_safe_get(wl_nvname("ssid", unit
, subunit
)),
1229 "imode", "bss", "amode", amode
);
1231 eval("wl", "-i", ifname
, "join", nvram_safe_get(wl_nvname("ssid", unit
, subunit
)));
1233 stacheck
= STACHECK_DISCONNECT
;
1249 static int radio_toggle(int idx
, int unit
, int subunit
, void *param
)
1251 if (!nvram_get_int(wl_nvname("radio", unit
, 0))) return 0;
1255 if (*op
== RADIO_TOGGLE
) {
1256 *op
= get_radio(unit
) ? RADIO_OFF
: RADIO_ON
;
1259 set_radio(*op
, unit
);
1263 int radio_main(int argc
, char *argv
[])
1270 usage_exit(argv
[0], "on|off|toggle|join [N]\n");
1272 unit
= (argc
== 3) ? atoi(argv
[2]) : -1;
1274 if (strcmp(argv
[1], "toggle") == 0)
1276 else if (strcmp(argv
[1], "off") == 0)
1278 else if (strcmp(argv
[1], "on") == 0)
1280 else if (strcmp(argv
[1], "join") == 0)
1286 op
= radio_toggle(0, unit
, 0, &op
);
1288 op
= foreach_wif(0, &op
, radio_toggle
);
1295 foreach_wif(1, &unit
, radio_join
);
1300 int wdist_main(int argc, char *argv[])
1309 if (wl_ioctl(nvram_safe_get("wl_ifname"), 101, &r, sizeof(r)) == 0) {
1312 else v = (v - (9 + 1)) * 150;
1313 printf("Current: %d-%dm (0x%02x)\n\n", v + (v ? 1 : 0), v + 150, r.val);
1315 usage_exit(argv[0], "<meters>");
1317 if ((n = atoi(argv[1])) <= 0) setup_wldistance();
1318 else set_wldistance(n);
1323 static int get_wldist(int idx
, int unit
, int subunit
, void *param
)
1327 char *p
= nvram_safe_get(wl_nvname("distance", unit
, 0));
1328 if ((*p
== 0) || ((n
= atoi(p
)) < 0)) return 0;
1330 return (9 + (n
/ 150) + ((n
% 150) ? 1 : 0));
1333 static int wldist(int idx
, int unit
, int subunit
, void *param
)
1340 n
= get_wldist(idx
, unit
, subunit
, param
);
1342 s
= 0x10 | (n
<< 16);
1343 p
= nvram_safe_get(wl_nvname("ifname", unit
, 0));
1344 wl_ioctl(p
, 197, &s
, sizeof(s
));
1349 wl_ioctl(p
, 102, &r
, sizeof(r
));
1355 int wldist_main(int argc
, char *argv
[])
1358 if (foreach_wif(0, NULL
, get_wldist
) == 0) return 0;
1361 foreach_wif(0, NULL
, wldist
);