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"));
105 if ((s
= nvram_get("lan1_ipaddr")) && (*s
) && (strcmp(s
,"") != 0))
106 fprintf(f
, "%s %s-lan1\n", s
, nvram_safe_get("lan_hostname"));
107 if ((s
= nvram_get("lan2_ipaddr")) && (*s
) && (strcmp(s
,"") != 0))
108 fprintf(f
, "%s %s-lan2\n", s
, nvram_safe_get("lan_hostname"));
109 if ((s
= nvram_get("lan3_ipaddr")) && (*s
) && (strcmp(s
,"") != 0))
110 fprintf(f
, "%s %s-lan3\n", s
, nvram_safe_get("lan_hostname"));
113 if (ipv6_enabled()) {
114 fprintf(f
, "::1 localhost\n");
115 s
= ipv6_router_address(NULL
);
116 if (*s
) fprintf(f
, "%s %s\n", s
, nvram_safe_get("lan_hostname"));
123 void set_host_domain_name(void)
127 s
= nvram_safe_get("wan_hostname");
128 sethostname(s
, strlen(s
));
131 s
= nvram_get("wan_domain");
132 if ((s
== NULL
) || (*s
== 0)) s
= nvram_safe_get("wan_get_domain");
133 setdomainname(s
, strlen(s
));
136 static int wlconf(char *ifname
, int unit
, int subunit
)
141 if (/* !wl_probe(ifname) && */ unit
>= 0) {
142 // validate nvram settings for wireless i/f
143 snprintf(wl
, sizeof(wl
), "--wl%d", unit
);
144 eval("nvram", "validate", wl
);
147 r
= eval("wlconf", ifname
, "up");
149 if (unit
>= 0 && subunit
<= 0) {
150 // setup primary wl interface
151 nvram_set("rrules_radio", "-1");
153 eval("wl", "-i", ifname
, "antdiv", nvram_safe_get(wl_nvname("antdiv", unit
, 0)));
154 eval("wl", "-i", ifname
, "txant", nvram_safe_get(wl_nvname("txant", unit
, 0)));
155 eval("wl", "-i", ifname
, "txpwr1", "-o", "-m", nvram_get_int(wl_nvname("txpwr", unit
, 0)) ? nvram_safe_get(wl_nvname("txpwr", unit
, 0)) : "-1");
156 eval("wl", "-i", ifname
, "interference", nvram_safe_get(wl_nvname("mitigation", unit
, 0)));
159 if (wl_client(unit
, subunit
)) {
160 if (nvram_match(wl_nvname("mode", unit
, subunit
), "wet")) {
161 ifconfig(ifname
, IFUP
|IFF_ALLMULTI
, NULL
, NULL
);
163 if (nvram_get_int(wl_nvname("radio", unit
, 0))) {
164 snprintf(wl
, sizeof(wl
), "%d", unit
);
165 xstart("radio", "join", wl
);
172 // -----------------------------------------------------------------------------
175 static void emf_mfdb_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
177 char word
[256], *next
;
180 /* Add/Delete MFDB entries corresponding to new interface */
181 foreach (word
, nvram_safe_get("emf_entry"), next
) {
183 mgrp
= strsep(&ifname
, ":");
185 if ((mgrp
== NULL
) || (ifname
== NULL
)) continue;
187 /* Add/Delete MFDB entry using the group addr and interface */
188 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
189 eval("emf", ((add
) ? "add" : "del"), "mfdb", lan_ifname
, mgrp
, ifname
);
194 static void emf_uffp_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
196 char word
[256], *next
;
199 /* Add/Delete UFFP entries corresponding to new interface */
200 foreach (word
, nvram_safe_get("emf_uffp_entry"), next
) {
203 if (ifname
== NULL
) continue;
205 /* Add/Delete UFFP entry for the interface */
206 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
207 eval("emf", ((add
) ? "add" : "del"), "uffp", lan_ifname
, ifname
);
212 static void emf_rtport_update(char *lan_ifname
, char *lan_port_ifname
, bool add
)
214 char word
[256], *next
;
217 /* Add/Delete RTPORT entries corresponding to new interface */
218 foreach (word
, nvram_safe_get("emf_rtport_entry"), next
) {
221 if (ifname
== NULL
) continue;
223 /* Add/Delete RTPORT entry for the interface */
224 if (lan_port_ifname
== NULL
|| strcmp(lan_port_ifname
, ifname
) == 0) {
225 eval("emf", ((add
) ? "add" : "del"), "rtport", lan_ifname
, ifname
);
230 static void start_emf(char *lan_ifname
)
233 eval("emf", "start", lan_ifname
);
235 /* Add the static MFDB entries */
236 emf_mfdb_update(lan_ifname
, NULL
, 1);
238 /* Add the UFFP entries */
239 emf_uffp_update(lan_ifname
, NULL
, 1);
241 /* Add the RTPORT entries */
242 emf_rtport_update(lan_ifname
, NULL
, 1);
245 static void stop_emf(char *lan_ifname
)
247 eval("emf", "stop", lan_ifname
);
248 eval("igs", "del", "bridge", lan_ifname
);
249 eval("emf", "del", "bridge", lan_ifname
);
253 // -----------------------------------------------------------------------------
255 /* Set initial QoS mode for all et interfaces that are up. */
256 void set_et_qos_mode(int sfd
)
261 struct ethtool_drvinfo info
;
263 qos
= (strcmp(nvram_safe_get("wl_wme"), "off") != 0);
264 for (i
= 1; i
<= DEV_NUMIFS
; i
++) {
266 if (ioctl(sfd
, SIOCGIFNAME
, &ifr
)) continue;
267 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
)) continue;
268 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) continue;
270 if (ioctl(sfd
, SIOCGIFFLAGS
, &ifr
)) continue;
271 /* if up (wan may not be up yet at this point) */
272 if (ifr
.ifr_flags
& IFF_UP
) {
273 ifrdata
= ifr
.ifr_data
;
274 memset(&info
, 0, sizeof(info
));
275 info
.cmd
= ETHTOOL_GDRVINFO
;
276 ifr
.ifr_data
= (caddr_t
)&info
;
277 if (ioctl(sfd
, SIOCETHTOOL
, &ifr
) >= 0) {
278 /* Set QoS for et & bcm57xx devices */
279 if (!strncmp(info
.driver
, "et", 2) ||
280 !strncmp(info
.driver
, "bcm57", 5)) {
281 ifr
.ifr_data
= (caddr_t
)&qos
;
282 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");
587 static int disabled_wl(int idx
, int unit
, int subunit
, void *param
)
591 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
593 // skip disabled wl vifs
594 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
595 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
603 char *lan_ifname
, *lan_ifnames
, *ifname
, *p
;
611 // HACK: When a virtual SSID is disabled, it requires two initialisation
612 if (foreach_wif(1, NULL
, disabled_wl
))
620 for(br
=0 ; br
<4 ; br
++) {
621 char bridge
[2] = "0";
629 strcat(tmp
, "_ifname");
630 lan_ifname
= nvram_safe_get(tmp
);
631 if (strncmp(lan_ifname
, "br", 2) == 0) {
634 strcat(tmp
, "_ifnames");
635 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
637 while ((ifname
= strsep(&p
, " ")) != NULL
) {
638 while (*ifname
== ' ') ++ifname
;
639 if (*ifname
== 0) continue;
641 unit
= -1; subunit
= -1;
643 // ignore disabled wl vifs
644 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
646 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
647 if (!nvram_get_int(nv
))
649 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
652 // get the instance number of the wl i/f
653 else if (wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
)))
656 is_client
|= wl_client(unit
, subunit
) && nvram_get_int(wl_nvname("radio", unit
, 0));
659 eval("wlconf", ifname
, "start"); /* start wl iface */
660 #endif // CONFIG_BCMWL5
666 else if (strcmp(lan_ifname
, "")) {
667 /* specific non-bridged lan iface */
668 eval("wlconf", lan_ifname
, "start");
670 #endif // CONFIG_BCMWL5
673 killall("wldist", SIGTERM
);
677 xstart("radio", "join");
681 void enable_ipv6(int enable
)
684 struct dirent
*dirent
;
687 if ((dir
= opendir("/proc/sys/net/ipv6/conf")) != NULL
) {
688 while ((dirent
= readdir(dir
)) != NULL
) {
689 if (strcmp("vlan1", dirent
->d_name
) &&
690 strcmp("eth0", dirent
->d_name
) &&
691 strcmp("all", dirent
->d_name
) &&
692 strcmp("eth1", dirent
->d_name
))
695 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", dirent
->d_name
);
696 f_write_string(s
, enable
? "0" : "1", 0, 0);
703 void accept_ra(const char *ifname
)
707 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/accept_ra", ifname
);
708 f_write_string(s
, "2", 0, 0);
710 sprintf(s
, "/proc/sys/net/ipv6/conf/%s/forwarding", ifname
);
711 f_write_string(s
, "2", 0, 0);
717 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
721 char *lan_ifnames
, *ifname
, *p
;
724 int unit
, subunit
, sta
;
737 foreach_wif(0, NULL
, set_wlmac
);
739 foreach_wif(1, NULL
, set_wlmac
);
743 enable_ipv6(ipv6_enabled()); //tell Kernel to disable/enable IPv6 for most interfaces
745 vlan0tag
= nvram_get_int("vlan0tag");
747 if ((sfd
= socket(AF_INET
, SOCK_RAW
, IPPROTO_RAW
)) < 0) return;
748 for(br
=0 ; br
<4 ; br
++) {
749 char bridge
[2] = "0";
757 strcat(tmp
, "_ifname");
758 lan_ifname
= strdup(nvram_safe_get(tmp
));
760 if (strncmp(lan_ifname
, "br", 2) == 0) {
761 _dprintf("%s: setting up the bridge %s\n", __FUNCTION__
, lan_ifname
);
763 eval("brctl", "addbr", lan_ifname
);
764 eval("brctl", "setfd", lan_ifname
, "0");
768 eval("brctl", "stp", lan_ifname
, nvram_safe_get(tmp
));
771 if (nvram_get_int("emf_enable")) {
772 eval("emf", "add", "bridge", lan_ifname
);
773 eval("igs", "add", "bridge", lan_ifname
);
779 strcat(tmp
, "_ipaddr");
780 inet_aton(nvram_safe_get(tmp
), (struct in_addr
*)&ip
);
787 strcat(tmp
, "_ifnames");
788 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
790 while ((iftmp
= strsep(&p
, " ")) != NULL
) {
791 while (*iftmp
== ' ') ++iftmp
;
792 if (*iftmp
== 0) continue;
795 unit
= -1; subunit
= -1;
797 // ignore disabled wl vifs
798 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.')) {
800 snprintf(nv
, sizeof(nv
) - 1, "%s_bss_enabled", ifname
);
801 if (!nvram_get_int(nv
))
803 if (get_ifname_unit(ifname
, &unit
, &subunit
) < 0)
806 set_wlmac(0, unit
, subunit
, NULL
);
810 wl_ioctl(ifname
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
));
813 if (strncmp(ifname
, "vlan", 4) == 0) {
814 if (sscanf(ifname
, "vlan%d", &vid
) == 1) {
815 snprintf(tmp
, sizeof(tmp
), "vlan%dvid", vid
);
816 vid_map
= nvram_get_int(tmp
);
817 if ((vid_map
< 1) || (vid_map
> 4094)) vid_map
= vlan0tag
| vid
;
818 snprintf(tmp
, sizeof(tmp
), "vlan%d", vid_map
);
823 // bring up interface
824 if (ifconfig(ifname
, IFUP
|IFF_ALLMULTI
, NULL
, NULL
) != 0) continue;
826 // set the logical bridge address to that of the first interface
827 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
829 (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0 &&
830 memcmp(ifr
.ifr_hwaddr
.sa_data
, "\0\0\0\0\0\0", ETHER_ADDR_LEN
) == 0)) {
831 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
832 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0) {
833 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
834 ifr
.ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
835 _dprintf("%s: setting MAC of %s bridge to %s\n", __FUNCTION__
,
836 ifr
.ifr_name
, ether_etoa(ifr
.ifr_hwaddr
.sa_data
, eabuf
));
837 ioctl(sfd
, SIOCSIFHWADDR
, &ifr
);
842 if (wlconf(ifname
, unit
, subunit
) == 0) {
843 const char *mode
= nvram_safe_get(wl_nvname("mode", unit
, subunit
));
845 if (strcmp(mode
, "wet") == 0) {
846 // Enable host DHCP relay
847 if (nvram_get_int("dhcp_relay")) {
848 wl_iovar_set(ifname
, "wet_host_mac", ifr
.ifr_hwaddr
.sa_data
, ETHER_ADDR_LEN
);
849 wl_iovar_setint(ifname
, "wet_host_ipv4", ip
);
853 sta
|= (strcmp(mode
, "sta") == 0);
854 if ((strcmp(mode
, "ap") != 0) && (strcmp(mode
, "wet") != 0)) continue;
856 eval("brctl", "addif", lan_ifname
, ifname
);
858 if (nvram_get_int("emf_enable"))
859 eval("emf", "add", "iface", lan_ifname
, ifname
);
863 if ((nvram_get_int("wan_islan")) && (br
==0) &&
864 ((get_wan_proto() == WP_DISABLED
) || (sta
))) {
865 ifname
= nvram_get("wan_ifnameX");
866 if (ifconfig(ifname
, IFUP
, NULL
, NULL
) == 0)
867 eval("brctl", "addif", lan_ifname
, ifname
);
873 // --- this shouldn't happen ---
874 else if (*lan_ifname
) {
875 ifconfig(lan_ifname
, IFUP
, NULL
, NULL
);
876 wlconf(lan_ifname
, -1, -1);
884 // Get current LAN hardware address
885 strlcpy(ifr
.ifr_name
, lan_ifname
, IFNAMSIZ
);
888 strcat(tmp
, "_hwaddr");
889 // if (ioctl(sfd, SIOCGIFHWADDR, &ifr) == 0) nvram_set("lan_hwaddr", ether_etoa(ifr.ifr_hwaddr.sa_data, eabuf));
890 if (ioctl(sfd
, SIOCGIFHWADDR
, &ifr
) == 0) nvram_set(tmp
, ether_etoa(ifr
.ifr_hwaddr
.sa_data
, eabuf
));
892 // Set initial QoS mode for LAN ports
893 set_et_qos_mode(sfd
);
897 // bring up and configure LAN interface
900 strcat(tmp
, "_ipaddr");
903 strcat(tmp2
, "_netmask");
904 ifconfig(lan_ifname
, IFUP
, nvram_safe_get(tmp
), nvram_safe_get(tmp2
));
910 set_lan_hostname(nvram_safe_get("wan_hostname"));
912 if ((get_wan_proto() == WP_DISABLED
) && (br
==0)) {
913 char *gateway
= nvram_safe_get("lan_gateway") ;
914 if ((*gateway
) && (strcmp(gateway
, "0.0.0.0") != 0)) {
916 while ((route_add(lan_ifname
, 0, "0.0.0.0", gateway
, "0.0.0.0") != 0) && (tries
-- > 0)) sleep(1);
917 _dprintf("%s: add gateway=%s tries=%d\n", __FUNCTION__
, gateway
, tries
);
926 if (nvram_get_int("emf_enable")) start_emf(lan_ifname
);
931 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
936 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
939 char *lan_ifnames
, *p
, *ifname
;
942 int vlan0tag
, vid
, vid_map
;
945 vlan0tag
= nvram_get_int("vlan0tag");
947 for(br
=0 ; br
<4 ; br
++) {
948 char bridge
[2] = "0";
956 strcat(tmp
, "_ifname");
957 lan_ifname
= nvram_safe_get(tmp
);
958 ifconfig(lan_ifname
, 0, NULL
, NULL
);
964 if (strncmp(lan_ifname
, "br", 2) == 0) {
966 stop_emf(lan_ifname
);
970 strcat(tmp
, "_ifnames");
971 if ((lan_ifnames
= strdup(nvram_safe_get(tmp
))) != NULL
) {
973 while ((iftmp
= strsep(&p
, " ")) != NULL
) {
974 while (*iftmp
== ' ') ++iftmp
;
975 if (*iftmp
== 0) continue;
978 if (strncmp(ifname
, "vlan", 4) == 0) {
979 if (sscanf(ifname
, "vlan%d", &vid
) == 1) {
980 snprintf(tmp
, sizeof(tmp
), "vlan%dvid", vid
);
981 vid_map
= nvram_get_int(tmp
);
982 if ((vid_map
< 1) || (vid_map
> 4094)) vid_map
= vlan0tag
| vid
;
983 snprintf(tmp
, sizeof(tmp
), "vlan%d", vid_map
);
987 eval("wlconf", ifname
, "down");
988 ifconfig(ifname
, 0, NULL
, NULL
);
989 eval("brctl", "delif", lan_ifname
, ifname
);
993 eval("brctl", "delbr", lan_ifname
);
995 else if (*lan_ifname
) {
996 eval("wlconf", lan_ifname
, "down");
999 _dprintf("%s %d\n", __FUNCTION__
, __LINE__
);
1002 static int is_sta(int idx
, int unit
, int subunit
, void *param
)
1004 return (nvram_match(wl_nvname("mode", unit
, subunit
), "sta") && (nvram_match(wl_nvname("bss_enabled", unit
, subunit
), "1")));
1007 void do_static_routes(int add
)
1011 char *dest
, *mask
, *gateway
, *metric
, *ifname
;
1014 if ((buf
= strdup(nvram_safe_get(add
? "routes_static" : "routes_static_saved"))) == NULL
) return;
1015 if (add
) nvram_set("routes_static_saved", buf
);
1016 else nvram_unset("routes_static_saved");
1018 while ((q
= strsep(&p
, ">")) != NULL
) {
1019 if (vstrsep(q
, "<", &dest
, &gateway
, &mask
, &metric
, &ifname
) != 5) continue;
1021 ifname
= nvram_safe_get(((strcmp(ifname
,"LAN")==0) ? "lan_ifname" :
1022 ((strcmp(ifname
,"LAN1")==0) ? "lan1_ifname" :
1023 ((strcmp(ifname
,"LAN2")==0) ? "lan2_ifname" :
1024 ((strcmp(ifname
,"LAN3")==0) ? "lan3_ifname" :
1025 ((*ifname
== 'W') ? "wan_iface" : "wan_ifname"))))));
1027 ifname
= nvram_safe_get((*ifname
== 'L') ? "lan_ifname" :
1028 ((*ifname
== 'W') ? "wan_iface" : "wan_ifname"));
1031 for (r
= 3; r
>= 0; --r
) {
1032 if (route_add(ifname
, atoi(metric
), dest
, gateway
, mask
) == 0) break;
1037 route_del(ifname
, atoi(metric
), dest
, gateway
, mask
);
1043 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
1044 && (modem_ipaddr
= nvram_safe_get("modem_ipaddr")) && *modem_ipaddr
&& !nvram_match("modem_ipaddr","0.0.0.0")
1045 && (!foreach_wif(1, NULL
, is_sta
)) ) {
1047 char *end
= rindex(modem_ipaddr
,'.')+1;
1048 unsigned char c
= atoi(end
);
1049 char *iface
= nvram_safe_get("wan_ifname");
1051 sprintf(ip
, "%.*s%hhu", end
-modem_ipaddr
, modem_ipaddr
, (unsigned char)(c
^1^((c
&2)^((c
&1)<<1))) );
1052 eval("ip", "addr", add
?"add":"del", ip
, "peer", modem_ipaddr
, "dev", iface
);
1057 void hotplug_net(void)
1059 char *interface
, *action
;
1062 if (((interface
= getenv("INTERFACE")) == NULL
) || ((action
= getenv("ACTION")) == NULL
)) return;
1064 _dprintf("hotplug net INTERFACE=%s ACTION=%s\n", interface
, action
);
1066 if ((strncmp(interface
, "wds", 3) == 0) &&
1067 (strcmp(action
, "register") == 0 || strcmp(action
, "add") == 0)) {
1068 ifconfig(interface
, IFUP
, NULL
, NULL
);
1069 lan_ifname
= nvram_safe_get("lan_ifname");
1071 if (nvram_get_int("emf_enable")) {
1072 eval("emf", "add", "iface", lan_ifname
, interface
);
1073 emf_mfdb_update(lan_ifname
, interface
, 1);
1074 emf_uffp_update(lan_ifname
, interface
, 1);
1075 emf_rtport_update(lan_ifname
, interface
, 1);
1078 if (strncmp(lan_ifname
, "br", 2) == 0) {
1079 eval("brctl", "addif", lan_ifname
, interface
);
1080 notify_nas(interface
);
1086 static int is_same_addr(struct ether_addr
*addr1
, struct ether_addr
*addr2
)
1089 for (i
= 0; i
< 6; i
++) {
1090 if (addr1
->octet
[i
] != addr2
->octet
[i
])
1096 #define WL_MAX_ASSOC 128
1097 static int check_wl_client(char *ifname
, int unit
, int subunit
)
1099 struct ether_addr bssid
;
1101 char buf
[WLC_IOCTL_MAXLEN
];
1102 struct maclist
*mlist
;
1104 int associated
, authorized
;
1106 *(uint32
*)buf
= WLC_IOCTL_MAXLEN
;
1107 if (wl_ioctl(ifname
, WLC_GET_BSSID
, &bssid
, ETHER_ADDR_LEN
) < 0 ||
1108 wl_ioctl(ifname
, WLC_GET_BSS_INFO
, buf
, WLC_IOCTL_MAXLEN
) < 0)
1111 bi
= (wl_bss_info_t
*)(buf
+ 4);
1112 if ((bi
->SSID_len
== 0) ||
1113 (bi
->BSSID
.octet
[0] + bi
->BSSID
.octet
[1] + bi
->BSSID
.octet
[2] +
1114 bi
->BSSID
.octet
[3] + bi
->BSSID
.octet
[4] + bi
->BSSID
.octet
[5] == 0))
1118 authorized
= strstr(nvram_safe_get(wl_nvname("akm", unit
, subunit
)), "psk") == 0;
1120 mlsize
= sizeof(struct maclist
) + (WL_MAX_ASSOC
* sizeof(struct ether_addr
));
1121 if ((mlist
= malloc(mlsize
)) != NULL
) {
1122 mlist
->count
= WL_MAX_ASSOC
;
1123 if (wl_ioctl(ifname
, WLC_GET_ASSOCLIST
, mlist
, mlsize
) == 0) {
1124 for (i
= 0; i
< mlist
->count
; ++i
) {
1125 if (is_same_addr(&mlist
->ea
[i
], &bi
->BSSID
)) {
1132 if (associated
&& !authorized
) {
1133 memset(mlist
, 0, mlsize
);
1134 mlist
->count
= WL_MAX_ASSOC
;
1135 strcpy((char*)mlist
, "autho_sta_list");
1136 if (wl_ioctl(ifname
, WLC_GET_VAR
, mlist
, mlsize
) == 0) {
1137 for (i
= 0; i
< mlist
->count
; ++i
) {
1138 if (is_same_addr(&mlist
->ea
[i
], &bi
->BSSID
)) {
1148 return (associated
&& authorized
);
1151 #define STACHECK_CONNECT 30
1152 #define STACHECK_DISCONNECT 5
1154 static int radio_join(int idx
, int unit
, int subunit
, void *param
)
1160 int *unit_filter
= param
;
1161 if (*unit_filter
>= 0 && *unit_filter
!= unit
) return 0;
1163 if (!nvram_get_int(wl_nvname("radio", unit
, 0)) || !wl_client(unit
, subunit
)) return 0;
1165 ifname
= nvram_safe_get(wl_nvname("ifname", unit
, subunit
));
1167 // skip disabled wl vifs
1168 if (strncmp(ifname
, "wl", 2) == 0 && strchr(ifname
, '.') &&
1169 !nvram_get_int(wl_nvname("bss_enabled", unit
, subunit
)))
1172 sprintf(f
, "/var/run/radio.%d.%d.pid", unit
, subunit
< 0 ? 0 : subunit
);
1173 if (f_read_string(f
, s
, sizeof(s
)) > 0) {
1174 if ((i
= atoi(s
)) > 1) {
1181 sprintf(s
, "%d", getpid());
1182 f_write(f
, s
, sizeof(s
), 0, 0644);
1184 int stacheck_connect
= nvram_get_int("sta_chkint");
1185 if (stacheck_connect
<= 0)
1186 stacheck_connect
= STACHECK_CONNECT
;
1189 while (get_radio(unit
) && wl_client(unit
, subunit
)) {
1191 if (check_wl_client(ifname
, unit
, subunit
)) {
1192 stacheck
= stacheck_connect
;
1195 eval("wl", "-i", ifname
, "disassoc");
1196 #ifdef CONFIG_BCMWL5
1197 char *amode
, *sec
= nvram_safe_get(wl_nvname("akm", unit
, subunit
));
1199 if (strstr(sec
, "psk2")) amode
= "wpa2psk";
1200 else if (strstr(sec
, "psk")) amode
= "wpapsk";
1201 else if (strstr(sec
, "wpa2")) amode
= "wpa2";
1202 else if (strstr(sec
, "wpa")) amode
= "wpa";
1203 else if (nvram_get_int(wl_nvname("auth", unit
, subunit
))) amode
= "shared";
1204 else amode
= "open";
1206 eval("wl", "-i", ifname
, "join", nvram_safe_get(wl_nvname("ssid", unit
, subunit
)),
1207 "imode", "bss", "amode", amode
);
1209 eval("wl", "-i", ifname
, "join", nvram_safe_get(wl_nvname("ssid", unit
, subunit
)));
1211 stacheck
= STACHECK_DISCONNECT
;
1227 static int radio_toggle(int idx
, int unit
, int subunit
, void *param
)
1229 if (!nvram_get_int(wl_nvname("radio", unit
, 0))) return 0;
1233 if (*op
== RADIO_TOGGLE
) {
1234 *op
= get_radio(unit
) ? RADIO_OFF
: RADIO_ON
;
1237 set_radio(*op
, unit
);
1241 int radio_main(int argc
, char *argv
[])
1248 usage_exit(argv
[0], "on|off|toggle|join [N]\n");
1250 unit
= (argc
== 3) ? atoi(argv
[2]) : -1;
1252 if (strcmp(argv
[1], "toggle") == 0)
1254 else if (strcmp(argv
[1], "off") == 0)
1256 else if (strcmp(argv
[1], "on") == 0)
1258 else if (strcmp(argv
[1], "join") == 0)
1264 op
= radio_toggle(0, unit
, 0, &op
);
1266 op
= foreach_wif(0, &op
, radio_toggle
);
1273 foreach_wif(1, &unit
, radio_join
);
1278 int wdist_main(int argc, char *argv[])
1287 if (wl_ioctl(nvram_safe_get("wl_ifname"), 101, &r, sizeof(r)) == 0) {
1290 else v = (v - (9 + 1)) * 150;
1291 printf("Current: %d-%dm (0x%02x)\n\n", v + (v ? 1 : 0), v + 150, r.val);
1293 usage_exit(argv[0], "<meters>");
1295 if ((n = atoi(argv[1])) <= 0) setup_wldistance();
1296 else set_wldistance(n);
1301 static int get_wldist(int idx
, int unit
, int subunit
, void *param
)
1305 char *p
= nvram_safe_get(wl_nvname("distance", unit
, 0));
1306 if ((*p
== 0) || ((n
= atoi(p
)) < 0)) return 0;
1308 return (9 + (n
/ 150) + ((n
% 150) ? 1 : 0));
1311 static int wldist(int idx
, int unit
, int subunit
, void *param
)
1318 n
= get_wldist(idx
, unit
, subunit
, param
);
1320 s
= 0x10 | (n
<< 16);
1321 p
= nvram_safe_get(wl_nvname("ifname", unit
, 0));
1322 wl_ioctl(p
, 197, &s
, sizeof(s
));
1327 wl_ioctl(p
, 102, &r
, sizeof(r
));
1333 int wldist_main(int argc
, char *argv
[])
1336 if (foreach_wif(0, NULL
, get_wldist
) == 0) return 0;
1339 foreach_wif(0, NULL
, wldist
);