1/*
2 * Network services
3 *
4 * Copyright (C) 2008, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id: network.c,v 1.145 2009/04/19 20:17:35 Exp $
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <errno.h>
18#include <syslog.h>
19#include <ctype.h>
20#include <string.h>
21#include <unistd.h>
22#include <sys/stat.h>
23#include <sys/ioctl.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26#include <net/if.h>
27#include <netinet/in.h>
28#include <arpa/inet.h>
29#include <net/if_arp.h>
30#include <signal.h>
31
32typedef u_int64_t u64;
33typedef u_int32_t u32;
34typedef u_int16_t u16;
35typedef u_int8_t u8;
36
37#include <linux/sockios.h>
38#include <linux/types.h>
39#include <linux/ethtool.h>
40
41#include <bcmnvram.h>
42#include <netconf.h>
43#include <shutils.h>
44#include <wlutils.h>
45#include <nvparse.h>
46#include <rc.h>
47#include <bcmutils.h>
48#include <etioctl.h>
49#include <bcmparams.h>
50
51bool emf_enabled = FALSE;
52
53static int
54add_routes(char *prefix, char *var, char *ifname)
55{
56	char word[80], *next;
57	char *ipaddr, *netmask, *gateway, *metric;
58	char tmp[100];
59
60	foreach(word, nvram_safe_get(strcat_r(prefix, var, tmp)), next) {
61		dprintf("add %s\n", word);
62
63		netmask = word;
64		ipaddr = strsep(&netmask, ":");
65		if (!ipaddr || !netmask)
66			continue;
67		gateway = netmask;
68		netmask = strsep(&gateway, ":");
69		if (!netmask || !gateway)
70			continue;
71		metric = gateway;
72		gateway = strsep(&metric, ":");
73		if (!gateway || !metric)
74			continue;
75
76		dprintf("add %s\n", ifname);
77
78		route_add(ifname, atoi(metric) + 1, ipaddr, gateway, netmask);
79	}
80
81	return 0;
82}
83
84static int
85del_routes(char *prefix, char *var, char *ifname)
86{
87	char word[80], *next;
88	char *ipaddr, *netmask, *gateway, *metric;
89	char tmp[100];
90
91	foreach(word, nvram_safe_get(strcat_r(prefix, var, tmp)), next) {
92		dprintf("add %s\n", word);
93
94		netmask = word;
95		ipaddr = strsep(&netmask, ":");
96		if (!ipaddr || !netmask)
97			continue;
98		gateway = netmask;
99		netmask = strsep(&gateway, ":");
100		if (!netmask || !gateway)
101			continue;
102		metric = gateway;
103		gateway = strsep(&metric, ":");
104		if (!gateway || !metric)
105			continue;
106
107		dprintf("add %s\n", ifname);
108
109		route_del(ifname, atoi(metric) + 1, ipaddr, gateway, netmask);
110	}
111
112	return 0;
113}
114
115static int
116add_lan_routes(char *lan_ifname)
117{
118	return add_routes("lan_", "route", lan_ifname);
119}
120
121static int
122del_lan_routes(char *lan_ifname)
123{
124	return del_routes("lan_", "route", lan_ifname);
125}
126
127/* Set initial QoS mode for all et interfaces that are up. */
128
129static void
130set_et_qos_mode(void)
131{
132	int i, s, qos;
133	struct ifreq ifr;
134	struct ethtool_drvinfo info;
135
136	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
137		return;
138
139	qos = (strcmp(nvram_safe_get("wl_wme"), "off") != 0);
140
141	for (i = 1; i <= DEV_NUMIFS; i ++) {
142		ifr.ifr_ifindex = i;
143		if (ioctl(s, SIOCGIFNAME, &ifr))
144			continue;
145		if (ioctl(s, SIOCGIFHWADDR, &ifr))
146			continue;
147		if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
148			continue;
149		if (ioctl(s, SIOCGIFFLAGS, &ifr))
150			continue;
151		if (!(ifr.ifr_flags & IFF_UP))
152			continue;
153		/* Set QoS for et & bcm57xx devices */
154		memset(&info, 0, sizeof(info));
155		info.cmd = ETHTOOL_GDRVINFO;
156		ifr.ifr_data = (caddr_t)&info;
157		if (ioctl(s, SIOCETHTOOL, &ifr) < 0)
158			continue;
159		if ((strncmp(info.driver, "et", 2) != 0) &&
160		    (strncmp(info.driver, "bcm57", 5) != 0))
161			continue;
162		ifr.ifr_data = (caddr_t)&qos;
163		ioctl(s, SIOCSETCQOS, &ifr);
164	}
165
166	close(s);
167}
168
169/*
170 * Carry out a socket request including openning and closing the socket
171 * Return -1 if failed to open socket (and perror); otherwise return
172 * result of ioctl
173 */
174static int
175soc_req(const char *name, int action, struct ifreq *ifr)
176{
177	int s;
178	int rv = 0;
179
180	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
181		perror("socket");
182		return -1;
183	}
184	strncpy(ifr->ifr_name, name, IFNAMSIZ);
185	rv = ioctl(s, action, ifr);
186	close(s);
187
188	return rv;
189}
190
191/* Check NVRam to see if "name" is explicitly enabled */
192static inline int
193wl_vif_enabled(const char *name, char *tmp)
194{
195	return (atoi(nvram_safe_get(strcat_r(name,"_bss_enabled",tmp))));
196}
197
198/* Set the HW address for interface "name" if present in NVRam */
199static void
200wl_vif_hwaddr_set(const char *name)
201{
202	int rc;
203	char *ea;
204	char hwaddr[20];
205	struct ifreq ifr;
206
207	snprintf(hwaddr, sizeof(hwaddr), "%s_hwaddr", name);
208	ea = nvram_get(hwaddr);
209	if (ea == NULL) {
210		fprintf(stderr, "NET: No hw addr found for %s\n", name);
211		return;
212	}
213
214	fprintf(stderr, "NET: Setting %s hw addr to %s\n", name, ea);
215	ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
216	ether_atoe(ea, (unsigned char *)ifr.ifr_hwaddr.sa_data);
217	if ((rc = soc_req(name, SIOCSIFHWADDR, &ifr)) < 0) {
218		fprintf(stderr, "NET: Error setting hw for %s; returned %d\n", name, rc);
219	}
220}
221
222#ifdef __CONFIG_EMF__
223void
224emf_mfdb_update(char *lan_ifname, char *lan_port_ifname, bool add)
225{
226	char word[256], *next;
227	char *mgrp, *ifname;
228
229	/* Add/Delete MFDB entries corresponding to new interface */
230	foreach (word, nvram_safe_get("emf_entry"), next) {
231		ifname = word;
232		mgrp = strsep(&ifname, ":");
233
234		if ((mgrp == 0) || (ifname == 0))
235			continue;
236
237		/* Add/Delete MFDB entry using the group addr and interface */
238		if (strcmp(lan_port_ifname, ifname) == 0) {
239			eval("emf", ((add) ? "add" : "del"),
240			     "mfdb", lan_ifname, mgrp, ifname);
241		}
242	}
243
244	return;
245}
246
247void
248emf_uffp_update(char *lan_ifname, char *lan_port_ifname, bool add)
249{
250	char word[256], *next;
251	char *ifname;
252
253	/* Add/Delete UFFP entries corresponding to new interface */
254	foreach (word, nvram_safe_get("emf_uffp_entry"), next) {
255		ifname = word;
256
257		if (ifname == 0)
258			continue;
259
260		/* Add/Delete UFFP entry for the interface */
261		if (strcmp(lan_port_ifname, ifname) == 0) {
262			eval("emf", ((add) ? "add" : "del"),
263			     "uffp", lan_ifname, ifname);
264		}
265	}
266
267	return;
268}
269
270void
271emf_rtport_update(char *lan_ifname, char *lan_port_ifname, bool add)
272{
273	char word[256], *next;
274	char *ifname;
275
276	/* Add/Delete RTPORT entries corresponding to new interface */
277	foreach (word, nvram_safe_get("emf_rtport_entry"), next) {
278		ifname = word;
279
280		if (ifname == 0)
281			continue;
282
283		/* Add/Delete RTPORT entry for the interface */
284		if (strcmp(lan_port_ifname, ifname) == 0) {
285			eval("emf", ((add) ? "add" : "del"),
286			     "rtport", lan_ifname, ifname);
287		}
288	}
289
290	return;
291}
292
293void
294start_emf(char *lan_ifname)
295{
296	char word[256], *next;
297	char *mgrp, *ifname;
298
299	if (!nvram_match("emf_enable", "1"))
300		return;
301
302	/* Start EMF */
303	eval("emf", "start", lan_ifname);
304
305	/* Add the static MFDB entries */
306	foreach (word, nvram_safe_get("emf_entry"), next) {
307		ifname = word;
308		mgrp = strsep(&ifname, ":");
309
310		if ((mgrp == 0) || (ifname == 0))
311			continue;
312
313		/* Add MFDB entry using the group addr and interface */
314		eval("emf", "add", "mfdb", lan_ifname, mgrp, ifname);
315	}
316
317	/* Add the UFFP entries */
318	foreach (word, nvram_safe_get("emf_uffp_entry"), next) {
319		ifname = word;
320		if (ifname == 0)
321			continue;
322
323		/* Add UFFP entry for the interface */
324		eval("emf", "add", "uffp", lan_ifname, ifname);
325	}
326
327	/* Add the RTPORT entries */
328	foreach (word, nvram_safe_get("emf_rtport_entry"), next) {
329		ifname = word;
330		if (ifname == 0)
331			continue;
332
333		/* Add RTPORT entry for the interface */
334		eval("emf", "add", "rtport", lan_ifname, ifname);
335	}
336
337	return;
338}
339
340void
341load_emf(void)
342{
343	/* Load the EMF & IGMP Snooper modules */
344	eval("insmod", "emf");
345	eval("insmod", "igs");
346
347	emf_enabled = TRUE;
348
349	return;
350}
351
352void
353unload_emf(void)
354{
355	if (!emf_enabled)
356		return;
357
358	/* Unload the EMF & IGMP Snooper modules */
359	eval("rmmod", "igs");
360	eval("rmmod", "emf");
361
362	emf_enabled = FALSE;
363
364	return;
365}
366#endif /* __CONFIG_EMF__ */
367
368
369void
370start_lan(void)
371{
372	char *lan_ifname = nvram_safe_get("lan_ifname");
373	char name[80], *next;
374	char tmp[100];
375	int i, s;
376	struct ifreq ifr;
377	char buf[255],*ptr;
378	char lan_stp[10];
379	char *lan_ifnames;
380	char lan_dhcp[10];
381	char lan_ipaddr[15];
382	char lan_netmask[15];
383	char lan_hwaddr[15];
384	char hwaddr[ETHER_ADDR_LEN];
385
386	/* The NVRAM variable lan_ifnames contains all the available interfaces.
387	 * This is used to build the unbridged interface list. Once the unbridged list
388	 * is built lan_interfaces is rebuilt with only the interfaces in the bridge
389	 */
390
391	dprintf("%s\n", lan_ifname);
392
393#ifdef DLNA
394#ifdef DLNA_DEBUG
395	char auto_ip[8];
396    strcpy(auto_ip, acosNvramConfig_get("dlna_auto_ip"));
397	cprintf("dlna_auto_ip: %s. \n", auto_ip);
398#endif
399	if(nvram_match("dlna_auto_ip", "1"))
400    {
401	    if(nvram_match("auto_ip_backup", "0"))
402	    {/* dlna_auto_ip changed from 0 to 1. */
403			nvram_set("auto_ip_backup", "1");
404			/* Set default Auto IP values. */
405			nvram_set("tmp_lan_ipaddr", nvram_get("lan_ipaddr"));
406			nvram_set("lan_ipaddr", "169.254.146.254");
407
408			nvram_set("tmp_lan_netmask", nvram_get("lan_netmask"));
409			nvram_set("lan_netmask", "255.255.0.0");
410
411			nvram_set("tmp_lan_proto", nvram_get("lan_proto"));
412            nvram_set("lan_proto", "static");
413
414			nvram_set("tmp_rip_enable", nvram_get("rip_enable"));
415            nvram_set("rip_enable", "0");
416
417			nvram_commit();
418	    }
419    }else{/* dlna_auto_ip = 0 */
420		if(nvram_match("auto_ip_backup", "1"))
421		{/* dlan_auto_ip changed from 1 to 0. */
422			/* If user had changed the value, don't use tmp values.*/
423			if(!nvram_match("tmp_lan_netmask", "null")&&
424				nvram_match(nvram_get("lan_netmask"), "255.255.0.0")){
425				nvram_set("lan_netmask", nvram_get("tmp_lan_netmask"));
426				nvram_set("tmp_lan_netmask", "null");
427			}
428			if(!nvram_match("tmp_lan_ipaddr", "null")&&
429				nvram_match(nvram_get("lan_ipaddr"), "169.254.146.254")){
430				nvram_set("lan_ipaddr", nvram_get("tmp_lan_ipaddr"));
431				nvram_set("tmp_lan_ipaddr", "null");
432			}
433			if(!nvram_match("tmp_lan_proto", "null")&&
434				nvram_match(nvram_get("lan_proto"), "static")){
435				nvram_set("lan_proto", nvram_get("tmp_lan_proto"));
436				nvram_set("tmp_lan_proto", "null");
437			}
438			if(!nvram_match("tmp_rip_enable", "null")&&
439				nvram_match(nvram_get("rip_enable"), "0")){
440				nvram_set("rip_enable", nvram_get("tmp_rip_enable"));
441				nvram_set("tmp_rip_enable", "null");
442			}
443			nvram_set("auto_ip_backup", "0");
444			nvram_commit();
445		}
446	}
447#ifdef DLNA_DEBUG
448	cprintf("-> netmask: %s\n", nvram_get("lan_netmask"));
449	cprintf("-> lan ip: %s\n", nvram_get("lan_ipaddr"));
450	cprintf("-> dhcp server: %s\n", nvram_get("lan_proto"));
451	cprintf("-> rip: %s\n", nvram_get("rip_enable"));
452#endif
453
454
455	//nvram_commit();
456#endif
457
458
459
460
461
462
463
464
465	/* Create links */
466	symlink("/sbin/rc", "/tmp/ldhclnt");
467
468
469	nvram_unset("unbridged_ifnames");
470	nvram_unset("br0_ifnames");
471	nvram_unset("br1_ifnames");
472
473#ifdef __CONFIG_EXTACS__
474	nvram_unset("acs_ifnames");
475#endif
476	/* If we're a travel router... then we need to make sure we get
477		 the primary wireless interface up before trying to attach slave
478		 interface(s) to the bridge */
479	if(nvram_match("ure_disable", "0") && nvram_match("router_disable", "0"))
480	{
481        //cprintf("--> wan0_ifname:%s\n", nvram_get("wan0_ifname"));
482		eval("wlconf", nvram_get("wan0_ifname"), "up");
483	}
484
485
486 	/* Bring up bridged interfaces */
487#if defined(CONFIG_RUSSIA_IPTV)
488    int max_bridge_num = MAX_NO_BRIDGE;
489    int ru_iptv_bridge = 0;
490    int ru_iptv_wlan1 = 0;
491    int ru_iptv_wlan2 = 0;
492    unsigned char iptv_intf_val = 0x00;
493    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
494    {
495        char iptv_intf[32];
496
497        strcpy(iptv_intf, nvram_get(NVRAM_IPTV_INTF));
498        sscanf(iptv_intf, "0x%02X", &iptv_intf_val);
499        if (iptv_intf_val & IPTV_WLAN_ALL)
500        {
501            max_bridge_num++;
502            ru_iptv_bridge = 1;
503            if (iptv_intf_val & IPTV_WLAN1)
504                ru_iptv_wlan1 = 1;
505            if (iptv_intf_val & IPTV_WLAN2)
506                ru_iptv_wlan2 = 1;
507        }
508        if (ru_iptv_wlan1)
509            eval("brctl", "delif", "br0", "eth1");
510        else
511            eval("brctl", "delif", "br1", "eth1");
512
513        if (ru_iptv_wlan2)
514            eval("brctl", "delif", "br0", "eth2");
515        else
516            eval("brctl", "delif", "br1", "eth2");
517    }
518    if (nvram_match(NVRAM_IPTV_ENABLED, "0")) {
519        eval("brctl", "delbr", "br1");
520    }
521#if 0
522	for(i=0; i < max_bridge_num; i++) {
523		if(!i) {
524			lan_ifname = nvram_safe_get("lan_ifname");
525			lan_ifnames = nvram_safe_get("lan_ifnames");
526		}
527		else {
528			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
529			lan_ifname = nvram_safe_get( tmp);
530			snprintf(tmp, sizeof(tmp), "lan%x_ifnames", i);
531			lan_ifnames = nvram_safe_get( tmp);
532		}
533        eval("ifconfig", lan_ifname, "down");
534        eval("brctl", "delbr", lan_ifname);
535	}
536#endif
537
538	for(i=0; i < max_bridge_num; i++) {
539#else /* CONFIG_RUSSIA_IPTV */
540	for(i=0; i < MAX_NO_BRIDGE; i++) {
541#endif /* CONFIG_RUSSIA_IPTV */
542		if(!i) {
543			lan_ifname = nvram_safe_get("lan_ifname");
544			snprintf(lan_stp, sizeof(lan_stp), "lan_stp" );
545			snprintf(lan_dhcp, sizeof(lan_dhcp), "lan_dhcp" );
546			snprintf(lan_ipaddr, sizeof(lan_ipaddr), "lan_ipaddr" );
547			snprintf(lan_hwaddr, sizeof(lan_hwaddr), "lan_hwaddr" );
548			snprintf(lan_netmask, sizeof(lan_netmask), "lan_netmask" );
549			lan_ifnames = nvram_safe_get("lan_ifnames");
550		}
551		else {
552			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
553			lan_ifname = nvram_safe_get( tmp);
554			snprintf(lan_stp, sizeof(lan_stp), "lan%x_stp", i);
555			snprintf(lan_dhcp, sizeof(lan_dhcp), "lan%x_dhcp",i );
556			snprintf(lan_ipaddr, sizeof(lan_ipaddr), "lan%x_ipaddr",i );
557			snprintf(lan_hwaddr, sizeof(lan_hwaddr), "lan%x_hwaddr",i );
558			snprintf(lan_netmask, sizeof(lan_netmask), "lan%x_netmask",i );
559			snprintf(tmp, sizeof(tmp), "lan%x_ifnames", i);
560			lan_ifnames = nvram_safe_get( tmp);
561		}
562		if (strncmp(lan_ifname, "br", 2) == 0) {
563			eval("brctl", "addbr", lan_ifname);
564
565			/* Bob added start to avoid sending router solicitation packets, 09/03/2009 */
566#ifdef INCLUDE_IPV6
567			sprintf(buf, "echo 0 > /proc/sys/net/ipv6/conf/%s/router_solicitations", lan_ifname);
568			system(buf);
569#endif
570			/* Bob added end to avoid sending router solicitation packets, 09/03/2009 */
571
572			eval("brctl", "setfd", lan_ifname, "0");
573			//if (nvram_match(lan_stp, "0"))
574			if (nvram_invmatch("wla_repeater", "1"))
575
576				eval("brctl", "stp", lan_ifname, "off");
577			else
578				eval("brctl", "stp", lan_ifname, "on");
579#ifdef __CONFIG_EMF__
580			if (nvram_match("emf_enable", "1")) {
581				eval("emf", "add", "bridge", lan_ifname);
582				eval("igs", "del", "bridge", lan_ifname);
583				eval("igs", "add", "bridge", lan_ifname);
584			}
585#endif /* __CONFIG_EMF__ */
586			memset(hwaddr, 0, sizeof(hwaddr));
587
588			foreach(name, lan_ifnames, next) {
589
590				if (strncmp(name, "wl", 2) == 0) {
591					if (!wl_vif_enabled(name, tmp)) {
592						continue; /* Ignore disabled WL VIF */
593					}
594					wl_vif_hwaddr_set(name);
595				}
596
597				/* Bring up interface. Ignore any bogus/unknown interfaces on the NVRAM list */
598                //cprintf("--> ifconfig %s up\n", name);
599#if 0
600                if(!strcmp(name, "eth2")){
601                    cprintf("give up enable eth2 for debugging.\n");
602                    continue;
603                }
604#endif
605				if (ifconfig(name, IFUP | IFF_ALLMULTI, NULL, NULL)){
606					perror("ifconfig");
607				}else{
608					/* Set the logical bridge address to that of the first interface */
609					if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
610						perror("socket");
611						continue;
612					}
613					strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
614					if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0 &&
615						memcmp(ifr.ifr_hwaddr.sa_data, "\0\0\0\0\0\0", ETHER_ADDR_LEN) == 0) {
616						strncpy(ifr.ifr_name, name, IFNAMSIZ);
617						if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {
618							strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
619							ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
620							ioctl(s, SIOCSIFHWADDR, &ifr);
621
622							memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
623						}
624					}
625					close(s);
626
627					/* If not a wl i/f then simply add it to the bridge */
628                    //cprintf("--> wlconf %s up\n", name);
629					if (eval("wlconf", name, "up")) {
630						if (eval("brctl", "addif", lan_ifname, name))
631							perror("brctl");
632						else{
633							snprintf(tmp, sizeof(tmp), "br%x_ifnames", i);
634							ptr = nvram_get(tmp);
635							if (ptr)
636								snprintf(buf,sizeof(buf),"%s %s",ptr,name);
637							else
638								strncpy(buf,name,sizeof(buf));
639							nvram_set(tmp,buf);
640						}
641#ifdef __CONFIG_EMF__
642						if (nvram_match("emf_enable", "1"))
643							eval("emf", "add", "iface", lan_ifname, name);
644#endif /* __CONFIG_EMF__ */
645					}else{
646						char mode[] = "wlXXXXXXXXXX_mode";
647						int unit;
648
649						/* get the instance number of the wl i/f */
650						wl_ioctl(name, WLC_GET_INSTANCE, &unit, sizeof(unit));
651
652						snprintf(mode, sizeof(mode), "wl%d_mode", unit);
653
654						/* WET specific configurations */
655						if (nvram_match(mode, "wet")) {
656							/* Receive all multicast frames in WET mode */
657							ifconfig(name, IFUP | IFF_ALLMULTI, NULL, NULL);
658
659							/* Enable host DHCP relay */
660							if (nvram_match("lan_dhcp", "1"))
661								wl_iovar_set(name, "wet_host_mac", ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
662						}
663						/* Dont attach the main wl i/f in wds */
664						if ( (strncmp(name, "wl", 2) != 0 ) && ( nvram_match(mode, "wds")) ){
665							/* Save this interface name in unbridged_ifnames
666							 * This behaviour is consistent with BEARS release
667							 */
668							ptr = nvram_get("unbridged_ifnames");
669							if (ptr)
670								snprintf(buf, sizeof(buf), "%s %s", ptr, name);
671							else
672								strncpy(buf, name, sizeof(buf));
673							nvram_set("unbridged_ifnames", buf);
674							continue;
675						}
676
677						eval("brctl", "addif", lan_ifname, name);
678#ifdef __CONFIG_EMF__
679						if (nvram_match("emf_enable", "1"))
680							eval("emf", "add", "iface", lan_ifname, name);
681#endif /* __CONFIG_EMF__ */
682
683						snprintf(tmp, sizeof(tmp), "br%x_ifnames", i);
684						ptr = nvram_get(tmp);
685						if (ptr)
686							snprintf(buf,sizeof(buf),"%s %s",ptr,name);
687						else
688							strncpy(buf,name,sizeof(buf));
689						nvram_set(tmp,buf);
690
691					} /*if (eval("wlconf", na.....*/
692
693				} /* if (ifconfig(name,...*/
694
695			} /* foreach().... */
696
697			if (memcmp(hwaddr, "\0\0\0\0\0\0", ETHER_ADDR_LEN) &&
698			    (s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
699				strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
700				ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
701				memcpy(ifr.ifr_hwaddr.sa_data, hwaddr, ETHER_ADDR_LEN);
702				ioctl(s, SIOCSIFHWADDR, &ifr);
703				close(s);
704			}
705		} /* if (strncmp(lan_ifname....*/
706		/* specific non-bridged lan i/f */
707		else if (strcmp(lan_ifname, "")) {
708			/* Bring up interface */
709            //cprintf("--> ifconfig %s up\n", lan_ifname);
710			ifconfig(lan_ifname, IFUP, NULL, NULL);
711			/* config wireless i/f */
712            //cprintf("--> wlconf %s up\n", lan_ifname);
713			eval("wlconf", lan_ifname, "up");
714		}
715		else
716			continue ; /* lanX_ifname is empty string , so donot do anything */
717
718		/* Get current LAN hardware address */
719		if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
720			char eabuf[32];
721			strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
722			if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0)
723				nvram_set(lan_hwaddr, ether_etoa((unsigned char *)ifr.ifr_hwaddr.sa_data, eabuf));
724			close(s);
725		}
726
727        /* Remove bridge DNS hijack module first.
728         * If we are in AP mode, this module will be
729         * inserted later again.
730         */
731#ifdef AP_MODE
732        system("/sbin/rmmod br_dns_hijack 2>/dev/null");
733#endif
734
735		/* Launch DHCP client - AP only */
736		if (nvram_match("router_disable", "1") && nvram_match(lan_dhcp, "1")) {
737			char *dhcp_argv[] = {
738				"udhcpc",
739				"-i", lan_ifname,
740				"-p", (sprintf(tmp, "/var/run/udhcpc-%s.pid", lan_ifname), tmp),
741				"-s", "/tmp/ldhclnt",
742				NULL
743			};
744			int pid;
745
746			/* Start dhcp daemon */
747			_eval(dhcp_argv, ">/dev/console", 0, &pid);
748		}
749        /* Auto IP mode. Now according to Router Spec 2.0,
750         * this is not related to UPnP/DLNA anymore,
751         * but related to "AP mode".
752         */
753#ifdef AP_MODE
754        else if (nvram_match("enable_ap_mode", "1")) {
755
756            /* In AP mode, we need to hijack some domain names,
757             * e.g. www.routerlogin.net
758             *      readyshare.routerlogin.net.
759             *      etc
760             * we use 'br_dns_hijack.ko for this purpose.
761             */
762            char command[128];
763#ifdef SAMBA_ENABLE
764            sprintf(command, "/sbin/insmod "
765                    "/lib/modules/2.6.22/kernel/lib/br_dns_hijack.ko "
766                    "readyshare_dev=%s",
767                    nvram_safe_get("smb_host_name"));
768#else
769            sprintf(command, "/sbin/insmod "
770                    "/lib/modules/2.6.22/kernel/lib/br_dns_hijack.ko "
771                    "readyshare_dev=\"\"");
772#endif
773            printf("command = '%s'\n", command);
774            system(command);
775
776            /* Insert acos_nat for logging purpose */
777#ifdef LINUX26
778            system("/bin/mknod -m 755 /dev/acos_nat_cli c 100 0");
779            system("/sbin/insmod /lib/modules/2.6.22/kernel/lib/acos_nat.ko");
780#else
781            system("/sbin/insmod /lib/modules/2.4.20/kernel/net/ipv4/acos_nat/acos_nat.o");
782#endif
783
784//#ifdef ISP_SK
785            char cmd[64];
786            /* Bring up WAN interface. */
787            sprintf(cmd, "ifconfig %s up", nvram_get("wan_ifname"));
788            system(cmd);
789            /* Bridge WAN interface into br0. */
790            sprintf(cmd, "brctl addif %s %s", nvram_get("lan_ifname"), nvram_get("wan_ifname"));
791            system(cmd);
792            /* Turn spanning tree for br0. */
793            sprintf(cmd, "brctl stp %s on", nvram_get("lan_ifname"));
794            system(cmd);
795//#endif /* ISP_SK */
796
797            /* Removed to start_services function in ap/acos/services.c */
798            /* We should start autoipd in start_services(this function called
799               after acos_init), because 'ntpclient' be called in autoipd and
800               'set_system_time' be called in acos_init,If acos_init execute
801               after autoipd, ntp time will be recoverd by set_system_time
802            */
803#if 0
804            if (nvram_match("ap_dyn_ip", "1")) {
805                /* Clear the NVRAM, so that heartbeat can show
806                 * the Internet LED correctly.
807                 */
808                nvram_set("lan_ipaddr", "0.0.0.0");
809                eval("autoipd");
810            }
811            else
812#endif
813                if (!nvram_match("ap_dyn_ip", "1")) {
814                char command[128];
815                FILE *fp;
816                char tmp[100];
817                char word[100], *next;
818                char line[100];
819                /* Use user-defined DNS servers if necessary */
820                char dns[256];
821
822                //use static settings from GUI
823                ifconfig(lan_ifname, IFUP, nvram_get("lan_ipaddr"),
824                            nvram_get("lan_netmask"));
825                sprintf (command, "route add default gw %s", nvram_get("apmode_gateway"));
826                system (command);
827
828                //Add dns
829                strcpy(dns, nvram_get("apmode_dns1"));
830                /* Open resolv.conf to read */
831                if (!(fp = fopen("/tmp/resolv.conf", "w+"))) {
832                    perror("/tmp/resolv.conf");
833                    return errno;
834                }
835                foreach(word, dns, next)
836                {
837
838                    fprintf(fp, "nameserver %s\n", word);
839                }
840                fclose(fp);
841        }
842    }
843#endif
844
845		/* Handle static IP address - AP or Router */
846		else {
847			/* Bring up and configure LAN interface */
848			ifconfig(lan_ifname, IFUP,
849				nvram_safe_get(lan_ipaddr), nvram_safe_get(lan_netmask));
850			/* We are done configuration */
851			lan_up(lan_ifname);
852		}
853
854#ifdef __CONFIG_EMF__
855		/* Start the EMF for this LAN */
856		start_emf(lan_ifname);
857#endif /* __CONFIG_EMF__ */
858	} /* For loop */
859
860#if defined(CONFIG_RUSSIA_IPTV)
861    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
862    {
863        if (iptv_intf_val & IPTV_WLAN_ALL)
864        {
865            eval("emf", "add", "bridge", "br1");
866            eval("igs", "add", "bridge", "br1");
867            eval("emf", "add", "iface", "br1", "eth0");
868            if (ru_iptv_wlan1)
869                eval("emf", "add", "iface", "br1", "eth1");
870            if (ru_iptv_wlan2)
871                eval("emf", "add", "iface", "br1", "eth2");
872            eval("emf", "start", "br1");
873        }
874    }
875#endif /* CONFIG_RUSSIA_IPTV */
876
877	/* Set initial QoS mode for LAN ports. */
878	set_et_qos_mode();
879
880	/* start syslogd if either log_ipaddr or log_ram_enable is set */
881	if (nvram_invmatch("log_ipaddr", "") || nvram_match("log_ram_enable", "1")) {
882#if !defined(__CONFIG_BUSYBOX__) || defined(BB_SYSLOGD)
883		char *argv[] = {
884			"syslogd",
885			NULL,		/* -C */
886			NULL, NULL,	/* -R host */
887			NULL
888		};
889		int pid;
890		int argc = 1;
891
892		if (nvram_match("log_ram_enable", "1"))
893			argv[argc++] = "-C";
894
895		if (nvram_invmatch("log_ipaddr", "")) {
896			argv[argc++] = "-R";
897			argv[argc++] = nvram_get("log_ipaddr");
898		}
899
900
901		_eval(argv, NULL, 0, &pid);
902#else /* Busybox configured w/o syslogd */
903		cprintf("Busybox configured w/o syslogd\n");
904#endif
905	}
906
907	dprintf("%s %s\n",
908		nvram_safe_get("lan_ipaddr"),
909		nvram_safe_get("lan_netmask"));
910
911}
912
913void
914stop_lan(void)
915{
916	char *lan_ifname = nvram_safe_get("lan_ifname");
917	char name[80], *next, signal[] = "XXXXXXXX";
918	char br_prefix[20];
919	char tmp[20];
920	int i=0;
921	char* lan_ifnames;
922
923	dprintf("%s\n", lan_ifname);
924
925	/* Stop the syslogd daemon */
926	eval("killall", "syslogd");
927	/* release the DHCP address and kill the client */
928	snprintf(signal, sizeof(signal), "-%d", SIGUSR2);
929	eval("killall", signal, "udhcpc");
930	eval("killall", "udhcpc");
931
932	/* Remove static routes */
933	del_lan_routes(lan_ifname);
934
935	/* Bring down unbridged interfaces,if any */
936	foreach(name, nvram_safe_get("unbridged_ifnames"), next) {
937		eval("wlconf", name, "down");
938		ifconfig(name, 0, NULL, NULL);
939	}
940
941#if defined(CONFIG_RUSSIA_IPTV)
942    int max_bridge_num = MAX_NO_BRIDGE;
943    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
944    {
945        char iptv_intf[32];
946        unsigned char iptv_intf_val = 0x00;
947
948        strcpy(iptv_intf, nvram_get(NVRAM_IPTV_INTF));
949        sscanf(iptv_intf, "0x%02X", &iptv_intf_val);
950        if (iptv_intf_val & IPTV_WLAN_ALL)
951        {
952            max_bridge_num++;
953        }
954    }
955	for(i=0; i < max_bridge_num; i++) {
956#else /* CONFIG_RUSSIA_IPTV */
957	for(i=0; i < MAX_NO_BRIDGE; i++) {
958#endif /* CONFIG_RUSSIA_IPTV */
959		if(!i) {
960			lan_ifname = nvram_safe_get("lan_ifname");
961			snprintf(br_prefix, sizeof(br_prefix), "br0_ifnames");
962		}
963		else {
964			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
965			lan_ifname = nvram_safe_get( tmp);
966			snprintf(br_prefix, sizeof(br_prefix), "br%x_ifnames",i);
967		}
968		if (!strcmp(lan_ifname, ""))
969			continue;
970
971#ifdef __CONFIG_EMF__
972		/* Stop the EMF for this LAN */
973		eval("emf", "stop", lan_ifname);
974#endif /* __CONFIG_EMF__ */
975		/* Bring down LAN interface */
976#if 0
977		ifconfig(lan_ifname, 0, NULL, NULL);
978
979		/* Bring down bridged interfaces */
980		if (strncmp(lan_ifname, "br", 2) == 0) {
981			lan_ifnames = nvram_safe_get(br_prefix);
982			foreach(name, lan_ifnames, next) {
983				eval("wlconf", name, "down");
984				ifconfig(name, 0, NULL, NULL);
985				eval("brctl", "delif", lan_ifname, name);
986			}
987			eval("brctl", "delbr", lan_ifname);
988		}
989		/* Bring down specific interface */
990		else if (strcmp(lan_ifname, ""))
991			eval("wlconf", lan_ifname, "down");
992#endif
993
994        /* We should delete eth0 from br0 for router mode */
995        if (nvram_match("enable_ap_mode", "0")) {
996            char cmd[64];
997            /* Delete WAN interface from br0. */
998            sprintf(cmd, "brctl delif %s %s", nvram_get("lan_ifname"), nvram_get("wan_ifname"));
999            system(cmd);
1000        }
1001	}
1002
1003	unlink("/tmp/ldhclnt");
1004
1005	dprintf("done\n");
1006}
1007
1008void
1009start_wl(void)
1010{
1011	int i;
1012	//char *lan_ifname = nvram_safe_get("lan_ifname");
1013	char lan_ifname[32];
1014	char name[80], *next;
1015	char tmp[100];
1016	//char *lan_ifnames;
1017	char lan_ifnames[32];
1018
1019	/* If we're a travel router... then we need to make sure we get
1020		 the primary wireless interface up before trying to attach slave
1021		 interface(s) to the bridge */
1022	if(nvram_match("ure_disable", "0") && nvram_match("router_disable", "0")) {
1023		/* start wlireless */
1024		eval("wlconf", nvram_get("wan0_ifname"), "start");
1025	}
1026
1027 	/* Bring up bridged interfaces */
1028#if defined(CONFIG_RUSSIA_IPTV)
1029    int max_bridge_num = MAX_NO_BRIDGE;
1030    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
1031    {
1032        char iptv_intf[32];
1033        unsigned char iptv_intf_val = 0x00;
1034
1035        strcpy(iptv_intf, nvram_get(NVRAM_IPTV_INTF));
1036        sscanf(iptv_intf, "0x%02X", &iptv_intf_val);
1037        if (iptv_intf_val & IPTV_WLAN_ALL)
1038        {
1039            max_bridge_num++;
1040        }
1041    }
1042	for(i=0; i < max_bridge_num; i++) {
1043#else /* CONFIG_RUSSIA_IPTV */
1044	for(i=0; i < MAX_NO_BRIDGE; i++) {
1045#endif /* CONFIG_RUSSIA_IPTV */
1046		if(!i) {
1047            /* Use char array to keep the nvram value instead of
1048             *  using pointers.
1049             */
1050#if 0
1051			lan_ifname = nvram_safe_get("lan_ifname");
1052			lan_ifnames = nvram_safe_get("lan_ifnames");
1053#endif
1054			strcpy(lan_ifname, nvram_safe_get("lan_ifname"));
1055			strcpy(lan_ifnames, nvram_safe_get("lan_ifnames"));
1056		}
1057		else {
1058			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
1059            /* Use char array to keep the nvram value instead of
1060             *  using pointers.
1061             */
1062			//lan_ifname = nvram_safe_get( tmp);
1063			strcpy(lan_ifname, nvram_safe_get( tmp));
1064			snprintf(tmp, sizeof(tmp), "lan%x_ifnames", i);
1065			//lan_ifnames = nvram_safe_get( tmp);
1066			strcpy(lan_ifnames, nvram_safe_get( tmp));
1067		}
1068		if (strncmp(lan_ifname, "br", 2) == 0) {
1069			foreach(name, lan_ifnames, next) {
1070				if (strncmp(name, "wl", 2) == 0) {
1071					if (!wl_vif_enabled(name, tmp)) {
1072						continue; /* Ignore disabled WL VIF */
1073					}
1074				}
1075				/* If a wl i/f, start it */
1076				eval("wlconf", name, "start");
1077
1078			} /* foreach().... */
1079		} /* if (strncmp(lan_ifname....*/
1080		/* specific non-bridged lan i/f */
1081		else if (strcmp(lan_ifname, "")) {
1082			/* start wireless i/f */
1083			eval("wlconf", lan_ifname, "start");
1084		}
1085	} /* For loop */
1086
1087
1088	if(nvram_match("wla_region", "3") || nvram_match("wla_region", "11") || nvram_match("wla_region", "9")|| nvram_match("wla_region", "8") || nvram_match("wla_region", "2") )  //AU or NA or Mexico or Asia or Korea
1089	{
1090		eval("wl", "country", "Q1/15");
1091		eval("wl", "-i", "eth2", "country", "Q1/15");
1092		system("wl -i eth2 txcore -o 4 -s 1 -c 4 -s 2 -c 7 -s 3 -c 7");	/* change 5G to SISO mode(MCS0!MCS7 ??) to improve performance, from HW */
1093	}
1094	else if(nvram_match("wla_region", "5"))
1095	{
1096		eval("wl", "country", "EU/22");
1097		eval("wl", "-i", "eth2", "country", "EU/22");
1098		system("wl -i eth2 txcore -o 7 -s 1 -c 7 -s 2 -c 7 -s 3 -c 7"); /* change to MIMO mode */
1099
1100                system("wl -i eth2 radarthrs 0x6CC 0x30 0x6C8 0x30 0x6C0 0x30 0x6B8 0x30");
1101
1102	}
1103    else if(nvram_match("wla_region", "7"))
1104	{
1105		eval("wl", "country", "JP/29");
1106		eval("wl", "-i", "eth2", "country", "JP/29");
1107		system("wl -i eth2 txcore -o 4 -s 1 -c 4 -s 2 -c 7 -s 3 -c 7");	/* change 5G to SISO mode(MCS0!MCS7 ??) to improve performance, from HW */
1108	}
1109        else if(nvram_match("wla_region", "14"))
1110	{
1111		eval("wl", "country", "RU/5");
1112		eval("wl", "-i", "eth2", "country", "RU/5");
1113                system("wl -i eth1 txcore -k 7 -o 7 -s 1 -c 7 -s 2 -c 7 -s 3 -c 7");
1114		system("wl -i eth2 txcore -o 4 -s 1 -c 4 -s 2 -c 7 -s 3 -c 7");
1115	}
1116	else
1117	{
1118		eval("wl", "country", "EU/22");
1119		eval("wl", "-i", "eth2", "country", "EU/22");
1120		system("wl -i eth2 txcore -o 7 -s 1 -c 7 -s 2 -c 7 -s 3 -c 7"); /* change to MIMO mode */
1121                system("wl -i eth2 radarthrs 0x6DC 0x30 0x6DC 0x30 0x6DC 0x30 0x6DC 0x30");
1122	}
1123        if(nvram_match("sku_name", "RU")){
1124           eval("wl", "country", "RU/5");
1125	   eval("wl", "-i", "eth2", "country", "RU/5");
1126           system("wl -i eth1 txcore -k 7 -o 7 -s 1 -c 7 -s 2 -c 7 -s 3 -c 7");
1127           system("wl -i eth2 txcore -o 4 -s 1 -c 4 -s 2 -c 7 -s 3 -c 7");	/* change 5G to SISO mode(MCS0!MCS7 ??) to improve performance, from HW */
1128        }
1129
1130}
1131
1132#ifdef __CONFIG_NAT__
1133static int
1134wan_prefix(char *ifname, char *prefix)
1135{
1136	int unit;
1137
1138	if ((unit = wan_ifunit(ifname)) < 0)
1139		return -1;
1140
1141	sprintf(prefix, "wan%d_", unit);
1142	return 0;
1143}
1144
1145static int
1146add_wan_routes(char *wan_ifname)
1147{
1148	char prefix[] = "wanXXXXXXXXXX_";
1149
1150	/* Figure out nvram variable name prefix for this i/f */
1151	if (wan_prefix(wan_ifname, prefix) < 0)
1152		return -1;
1153
1154	return add_routes(prefix, "route", wan_ifname);
1155}
1156
1157static int
1158del_wan_routes(char *wan_ifname)
1159{
1160	char prefix[] = "wanXXXXXXXXXX_";
1161
1162	/* Figure out nvram variable name prefix for this i/f */
1163	if (wan_prefix(wan_ifname, prefix) < 0)
1164		return -1;
1165
1166	return del_routes(prefix, "route", wan_ifname);
1167}
1168
1169static int
1170wan_valid(char *ifname)
1171{
1172	char name[80], *next;
1173
1174	foreach(name, nvram_safe_get("wan_ifnames"), next)
1175		if (ifname && !strcmp(ifname, name))
1176			return 1;
1177	return 0;
1178}
1179
1180void
1181start_wan(void)
1182{
1183	char *wan_ifname;
1184	char *wan_proto;
1185	int unit;
1186	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1187	char eabuf[32];
1188	int s;
1189	struct ifreq ifr;
1190	pid_t pid;
1191
1192	/* check if we need to setup WAN */
1193	if (nvram_match("router_disable", "1"))
1194		return;
1195
1196
1197	/* start connection independent firewall */
1198	start_firewall();
1199
1200	/* Create links */
1201	mkdir("/tmp/ppp", 0777);
1202	symlink("/sbin/rc", "/tmp/ppp/ip-up");
1203	symlink("/sbin/rc", "/tmp/ppp/ip-down");
1204
1205	symlink("/sbin/rc", "/tmp/udhcpc");
1206
1207	/* Start each configured and enabled wan connection and its undelying i/f */
1208	for (unit = 0; unit < MAX_NVPARSE; unit ++) {
1209		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
1210
1211		/* make sure the connection exists and is enabled */
1212		wan_ifname = nvram_get(strcat_r(prefix, "ifname", tmp));
1213		if (!wan_ifname)
1214			continue;
1215		wan_proto = nvram_get(strcat_r(prefix, "proto", tmp));
1216		if (!wan_proto || !strcmp(wan_proto, "disabled"))
1217			continue;
1218
1219		/* disable the connection if the i/f is not in wan_ifnames */
1220		if (!wan_valid(wan_ifname)) {
1221			nvram_set(strcat_r(prefix, "proto", tmp), "disabled");
1222			continue;
1223		}
1224
1225		dprintf("%s %s\n", wan_ifname, wan_proto);
1226
1227		/* Set i/f hardware address before bringing it up */
1228		if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
1229			continue;
1230		strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
1231
1232		/* Configure i/f only once, specially for wl i/f shared by multiple connections */
1233		if (ioctl(s, SIOCGIFFLAGS, &ifr)) {
1234			close(s);
1235			continue;
1236		}
1237
1238		if (!(ifr.ifr_flags & IFF_UP)) {
1239			/* Sync connection nvram address and i/f hardware address */
1240			memset(ifr.ifr_hwaddr.sa_data, 0, ETHER_ADDR_LEN);
1241			if (!nvram_invmatch(strcat_r(prefix, "hwaddr", tmp), "") ||
1242			    !ether_atoe(nvram_safe_get(strcat_r(prefix, "hwaddr", tmp)),
1243					(unsigned char *)ifr.ifr_hwaddr.sa_data) ||
1244			    !memcmp(ifr.ifr_hwaddr.sa_data, "\0\0\0\0\0\0", ETHER_ADDR_LEN)) {
1245				if (ioctl(s, SIOCGIFHWADDR, &ifr)) {
1246					close(s);
1247					continue;
1248				}
1249				nvram_set(strcat_r(prefix, "hwaddr", tmp),
1250					  ether_etoa((unsigned char *)ifr.ifr_hwaddr.sa_data, eabuf));
1251			} else {
1252				ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1253				ioctl(s, SIOCSIFHWADDR, &ifr);
1254			}
1255
1256			/* Bring up i/f */
1257			ifconfig(wan_ifname, IFUP, NULL, NULL);
1258
1259			/* do wireless specific config */
1260			if (nvram_match("ure_disable", "1")) {
1261				eval("wlconf", wan_ifname, "up");
1262				eval("wlconf", wan_ifname, "start");
1263			}
1264		}
1265
1266		close(s);
1267
1268		/* Set initial QoS mode again now that WAN port is ready. */
1269		set_et_qos_mode();
1270
1271		/*
1272		* Configure PPPoE connection. The PPPoE client will run
1273		* ip-up/ip-down scripts upon link's connect/disconnect.
1274		*/
1275		if (strcmp(wan_proto, "pppoe") == 0) {
1276			char *pppoe_argv[] = {
1277				"pppoecd",
1278				nvram_safe_get(strcat_r(prefix, "ifname", tmp)),
1279				"-u", nvram_safe_get(strcat_r(prefix, "pppoe_username", tmp)),
1280				"-p", nvram_safe_get(strcat_r(prefix, "pppoe_passwd", tmp)),
1281				"-r", nvram_safe_get(strcat_r(prefix, "pppoe_mru", tmp)),
1282				"-t", nvram_safe_get(strcat_r(prefix, "pppoe_mtu", tmp)),
1283				"-i", nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1") ?
1284				nvram_safe_get(strcat_r(prefix, "pppoe_idletime", tmp)) : "0",
1285				NULL, NULL,	/* pppoe_service */
1286				NULL, NULL,	/* pppoe_ac */
1287				NULL,		/* pppoe_keepalive */
1288				NULL, NULL,	/* ppp unit requested */
1289				NULL
1290			}, **arg;
1291			int timeout = 5;
1292			char pppunit[] = "XXXXXXXXXXXX";
1293
1294			/* Add optional arguments */
1295			for (arg = pppoe_argv; *arg; arg++);
1296			if (nvram_invmatch(strcat_r(prefix, "pppoe_service", tmp), "")) {
1297				*arg++ = "-s";
1298				*arg++ = nvram_safe_get(strcat_r(prefix, "pppoe_service", tmp));
1299			}
1300			if (nvram_invmatch(strcat_r(prefix, "pppoe_ac", tmp), "")) {
1301				*arg++ = "-a";
1302				*arg++ = nvram_safe_get(strcat_r(prefix, "pppoe_ac", tmp));
1303			}
1304			if (nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1") ||
1305			    nvram_match(strcat_r(prefix, "pppoe_keepalive", tmp), "1"))
1306				*arg++ = "-k";
1307			snprintf(pppunit, sizeof(pppunit), "%d", unit);
1308			*arg++ = "-U";
1309			*arg++ = pppunit;
1310
1311			/* launch pppoe client daemon */
1312			_eval(pppoe_argv, NULL, 0, &pid);
1313
1314			/* ppp interface name is referenced from this point on */
1315			wan_ifname = nvram_safe_get(strcat_r(prefix, "pppoe_ifname", tmp));
1316
1317			/* Pretend that the WAN interface is up */
1318			if (nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1")) {
1319				/* Wait for pppx to be created */
1320				while (ifconfig(wan_ifname, IFUP, NULL, NULL) && timeout--)
1321					sleep(1);
1322
1323				/* Retrieve IP info */
1324				if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
1325					continue;
1326				strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
1327
1328				/* Set temporary IP address */
1329				if (ioctl(s, SIOCGIFADDR, &ifr))
1330					perror(wan_ifname);
1331				nvram_set(strcat_r(prefix, "ipaddr", tmp), inet_ntoa(sin_addr(&ifr.ifr_addr)));
1332				nvram_set(strcat_r(prefix, "netmask", tmp), "255.255.255.255");
1333
1334				/* Set temporary P-t-P address */
1335				if (ioctl(s, SIOCGIFDSTADDR, &ifr))
1336					perror(wan_ifname);
1337				nvram_set(strcat_r(prefix, "gateway", tmp), inet_ntoa(sin_addr(&ifr.ifr_dstaddr)));
1338
1339				close(s);
1340
1341				/*
1342				* Preset routes so that traffic can be sent to proper pppx even before
1343				* the link is brought up.
1344				*/
1345				preset_wan_routes(wan_ifname);
1346			}
1347		}
1348		/*
1349		* Configure DHCP connection. The DHCP client will run
1350		* 'udhcpc bound'/'udhcpc deconfig' upon finishing IP address
1351		* renew and release.
1352		*/
1353		else if (strcmp(wan_proto, "dhcp") == 0) {
1354			char *wan_hostname = nvram_safe_get(strcat_r(prefix, "hostname", tmp));
1355			char *dhcp_argv[] = { "udhcpc",
1356					      "-i", wan_ifname,
1357					      "-p", (sprintf(tmp, "/var/run/udhcpc%d.pid", unit), tmp),
1358					      "-s", "/tmp/udhcpc",
1359					      wan_hostname && *wan_hostname ? "-H" : NULL,
1360					      wan_hostname && *wan_hostname ? wan_hostname : NULL,
1361					      NULL
1362			};
1363			/* Start dhcp client */
1364			_eval(dhcp_argv, NULL, 0, &pid);
1365		}
1366		/* Configure static IP connection. */
1367		else if (strcmp(wan_proto, "static") == 0) {
1368			/* Assign static IP address to i/f */
1369			ifconfig(wan_ifname, IFUP,
1370				 nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
1371				 nvram_safe_get(strcat_r(prefix, "netmask", tmp)));
1372			/* We are done configuration */
1373			wan_up(wan_ifname);
1374		}
1375
1376		/* Start connection dependent firewall */
1377		start_firewall2(wan_ifname);
1378
1379		dprintf("%s %s\n",
1380			nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
1381			nvram_safe_get(strcat_r(prefix, "netmask", tmp)));
1382	}
1383
1384	/* Report stats */
1385	if (nvram_invmatch("stats_server", "")) {
1386		char *stats_argv[] = { "stats", nvram_get("stats_server"), NULL };
1387		_eval(stats_argv, NULL, 5, NULL);
1388	}
1389}
1390
1391void
1392stop_wan(void)
1393{
1394	char name[80], *next, signal[] = "XXXX";
1395
1396#ifdef BCMQOS
1397		del_iQosRules();
1398#endif /* BCMQOS */
1399	eval("killall", "stats");
1400	eval("killall", "ntpclient");
1401
1402	/* Shutdown and kill all possible tasks */
1403	eval("killall", "ip-up");
1404	eval("killall", "ip-down");
1405	snprintf(signal, sizeof(signal), "-%d", SIGHUP);
1406	eval("killall", signal, "pppoecd");
1407	eval("killall", "pppoecd");
1408	snprintf(signal, sizeof(signal), "-%d", SIGUSR2);
1409	eval("killall", signal, "udhcpc");
1410	eval("killall", "udhcpc");
1411
1412	/* Bring down WAN interfaces */
1413	foreach(name, nvram_safe_get("wan_ifnames"), next)
1414		ifconfig(name, 0, "0.0.0.0", NULL);
1415
1416	/* Remove dynamically created links */
1417	unlink("/tmp/udhcpc");
1418
1419	unlink("/tmp/ppp/ip-up");
1420	unlink("/tmp/ppp/ip-down");
1421	rmdir("/tmp/ppp");
1422
1423	dprintf("done\n");
1424}
1425
1426static int
1427add_ns(char *wan_ifname)
1428{
1429	FILE *fp;
1430	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1431	char word[100], *next;
1432	char line[100];
1433
1434	/* Figure out nvram variable name prefix for this i/f */
1435	if (wan_prefix(wan_ifname, prefix) < 0)
1436		return -1;
1437
1438	/* Open resolv.conf to read */
1439	if (!(fp = fopen("/tmp/resolv.conf", "r+"))) {
1440		perror("/tmp/resolv.conf");
1441		return errno;
1442	}
1443	/* Append only those not in the original list */
1444	foreach(word, nvram_safe_get(strcat_r(prefix, "dns", tmp)), next) {
1445		fseek(fp, 0, SEEK_SET);
1446		while (fgets(line, sizeof(line), fp)) {
1447			char *token = strtok(line, " \t\n");
1448
1449			if (!token || strcmp(token, "nameserver") != 0)
1450				continue;
1451			if (!(token = strtok(NULL, " \t\n")))
1452				continue;
1453
1454			if (!strcmp(token, word))
1455				break;
1456		}
1457		if (feof(fp))
1458			fprintf(fp, "nameserver %s\n", word);
1459	}
1460	fclose(fp);
1461
1462	/* notify dnsmasq */
1463	snprintf(tmp, sizeof(tmp), "-%d", SIGHUP);
1464	eval("killall", tmp, "dnsmasq");
1465
1466	return 0;
1467}
1468
1469static int
1470del_ns(char *wan_ifname)
1471{
1472	FILE *fp, *fp2;
1473	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1474	char word[100], *next;
1475	char line[100];
1476
1477	/* Figure out nvram variable name prefix for this i/f */
1478	if (wan_prefix(wan_ifname, prefix) < 0)
1479		return -1;
1480
1481	/* Open resolv.conf to read */
1482	if (!(fp = fopen("/tmp/resolv.conf", "r"))) {
1483		perror("fopen /tmp/resolv.conf");
1484		return errno;
1485	}
1486	/* Open resolv.tmp to save updated name server list */
1487	if (!(fp2 = fopen("/tmp/resolv.tmp", "w"))) {
1488		perror("fopen /tmp/resolv.tmp");
1489		fclose(fp);
1490		return errno;
1491	}
1492	/* Copy updated name servers */
1493	while (fgets(line, sizeof(line), fp)) {
1494		char *token = strtok(line, " \t\n");
1495
1496		if (!token || strcmp(token, "nameserver") != 0)
1497			continue;
1498		if (!(token = strtok(NULL, " \t\n")))
1499			continue;
1500
1501		foreach(word, nvram_safe_get(strcat_r(prefix, "dns", tmp)), next)
1502			if (!strcmp(word, token))
1503				break;
1504		if (!next)
1505			fprintf(fp2, "nameserver %s\n", token);
1506	}
1507	fclose(fp);
1508	fclose(fp2);
1509	/* Use updated file as resolv.conf */
1510	unlink("/tmp/resolv.conf");
1511	rename("/tmp/resolv.tmp", "/tmp/resolv.conf");
1512
1513	/* notify dnsmasq */
1514	snprintf(tmp, sizeof(tmp), "-%d", SIGHUP);
1515	eval("killall", tmp, "dnsmasq");
1516
1517	return 0;
1518}
1519
1520/*
1521*/
1522#ifdef __CONFIG_IPV6__
1523/* Start the 6to4 Tunneling interface.
1524*	Return > 0: number of interfaces processed by this routine.
1525*		==0: skipped since no action is required.
1526*		< 0: Error number
1527*/
1528static int
1529start_6to4(char *wan_ifname)
1530{
1531	int i, ret = 0;
1532	int siMode, siCount;
1533	unsigned short uw6to4ID;
1534	in_addr_t uiWANIP;
1535	char *pcLANIF, *pcWANIP, tmp[64], prefix[] = "wanXXXXXXXXXX_";
1536
1537	/* Figure out nvram variable name prefix for this i/f */
1538	if (wan_prefix(wan_ifname, prefix) < 0)
1539		return 0;
1540
1541	pcWANIP = nvram_safe_get(strcat_r(prefix, "ipaddr", tmp));
1542	uiWANIP = inet_network(pcWANIP);
1543
1544	/* Check if the wan IP is private(RFC1918). 6to4 needs a global IP */
1545	if ((uiWANIP == 0) || (uiWANIP == -1) ||
1546		(uiWANIP & 0xffff0000) == 0xc0a80000 || /* 192.168.x.x */
1547		(uiWANIP & 0xfff00000) == 0xac100000 || /* 172.16.x.x */
1548		(uiWANIP & 0xff000000) == 0x0a000000) /* 10.x.x.x */
1549		return 0;
1550
1551	/* Create 6to4 intrface and setup routing table */
1552	for (i = 0, siCount = 0; i < MAX_NO_BRIDGE; i++) {
1553		if (i == 0) {
1554			pcLANIF = nvram_safe_get("lan_ifname");
1555			siMode = atoi(nvram_safe_get("lan_ipv6_mode"));
1556			uw6to4ID = (unsigned short)atoi(nvram_safe_get("lan_ipv6_6to4id"));
1557		}
1558		else {
1559			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
1560			pcLANIF = nvram_safe_get(tmp);
1561			snprintf(tmp, sizeof(tmp), "lan%x_ipv6_mode", i);
1562			siMode = atoi(nvram_safe_get(tmp));
1563			snprintf(tmp, sizeof(tmp), "lan%x_ipv6_6to4id", i);
1564			uw6to4ID = (unsigned short)atoi(nvram_safe_get(tmp));
1565		}
1566
1567		if (siMode & IPV6_6TO4_ENABLED) {
1568			/* Add the 6to4 route. */
1569			snprintf(tmp, sizeof(tmp), "2002:%x:%x:%x::/64",
1570				(unsigned short)(uiWANIP>>16), (unsigned short)uiWANIP,	uw6to4ID);
1571			ret = eval("/usr/sbin/ip", "-6", "route", "add", tmp,
1572				"dev", pcLANIF, "metric", "1");
1573			siCount++;
1574		}
1575	}
1576
1577	if (siCount == 0)
1578		return 0;
1579
1580	/* Create 6to4 intrface and setup routing table */
1581	{
1582		char *pc6to4IF = "v6to4"; /* The 6to4 tunneling interface name */
1583
1584		/* Create the tunneling interface */
1585		ret = eval("/usr/sbin/ip", "tunnel", "add", pc6to4IF,
1586			"mode", "sit", "ttl", "64", "remote", "any", "local", pcWANIP);
1587
1588		/* Bring the device up */
1589		ret = eval("/usr/sbin/ip", "link", "set", "dev", pc6to4IF, "up");
1590
1591		/* Add 6to4 v4 anycast route to the global IPv6 network */
1592		ret = eval("/usr/sbin/ip", "-6", "route", "add", "2000::/3",
1593			"via", "::192.88.99.1", "dev", pc6to4IF, "metric", "1");
1594	}
1595
1596#ifdef __CONFIG_RADVD__
1597	/* Restart radvd */
1598	{
1599		char acSignal[64];
1600
1601		snprintf(acSignal, sizeof(acSignal), "-%d", SIGHUP);
1602		ret = eval("killall", acSignal, "radvd");
1603	}
1604#endif /* __CONFIG_RADVD__ */
1605
1606#ifdef __CONFIG_NAT__
1607	/* Enable IPv6 protocol=41(0x29) on v4NAT */
1608	{
1609		char *pcWANIF;
1610
1611		pcWANIF = nvram_match("wan_proto", "pppoe")?
1612			nvram_safe_get("wan_pppoe_ifname"): nvram_safe_get("wan_ifname");
1613		add_ipv6_filter(nvram_safe_get(pcWANIF));
1614	}
1615#endif /* __CONFIG_NAT__ */
1616
1617	return siCount;
1618}
1619#endif /* __CONFIG_IPV6__ */
1620/*
1621*/
1622
1623void
1624wan_up(char *wan_ifname)
1625{
1626	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1627	char *wan_proto;
1628
1629	/* Figure out nvram variable name prefix for this i/f */
1630	if (wan_prefix(wan_ifname, prefix) < 0)
1631		return;
1632
1633	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
1634
1635	dprintf("%s %s\n", wan_ifname, wan_proto);
1636
1637	/* Set default route to gateway if specified */
1638	if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1639		route_add(wan_ifname, 0, "0.0.0.0",
1640			nvram_safe_get(strcat_r(prefix, "gateway", tmp)),
1641			"0.0.0.0");
1642
1643	/* Install interface dependent static routes */
1644	add_wan_routes(wan_ifname);
1645
1646	/* Add dns servers to resolv.conf */
1647	add_ns(wan_ifname);
1648
1649	/* Sync time */
1650	start_ntpc();
1651#ifdef BCMQOS
1652    add_iQosRules(wan_ifname);
1653	start_iQos();
1654#endif /* BCMQOS */
1655
1656/*
1657*/
1658#ifdef __CONFIG_IPV6__
1659	start_6to4(wan_ifname);
1660#endif /* __CONFIG_IPV6__ */
1661/*
1662*/
1663
1664	dprintf("done\n");
1665}
1666
1667void
1668wan_down(char *wan_ifname)
1669{
1670	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1671	char *wan_proto;
1672
1673	/* Figure out nvram variable name prefix for this i/f */
1674	if (wan_prefix(wan_ifname, prefix) < 0)
1675		return;
1676
1677	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
1678
1679	printf("%s %s\n", wan_ifname, wan_proto);
1680
1681	/* Remove default route to gateway if specified */
1682	if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1683		route_del(wan_ifname, 0, "0.0.0.0",
1684			nvram_safe_get(strcat_r(prefix, "gateway", tmp)),
1685			"0.0.0.0");
1686
1687	/* Remove interface dependent static routes */
1688	del_wan_routes(wan_ifname);
1689
1690	/* Update resolv.conf */
1691	del_ns(wan_ifname);
1692
1693	dprintf("done\n");
1694}
1695#endif	/* __CONFIG_NAT__ */
1696
1697/* Enable WET DHCP relay for ethernet clients */
1698static int
1699enable_dhcprelay(char *ifname)
1700{
1701	char name[80], *next;
1702
1703	dprintf("%s\n", ifname);
1704
1705	/* WET interface is meaningful only in bridged environment */
1706	if (strncmp(ifname, "br", 2) == 0) {
1707		foreach(name, nvram_safe_get("lan_ifnames"), next) {
1708			char mode[] = "wlXXXXXXXXXX_mode";
1709			int unit;
1710
1711			/* make sure the interface is indeed of wl */
1712			if (wl_probe(name))
1713				continue;
1714
1715			/* get the instance number of the wl i/f */
1716			wl_ioctl(name, WLC_GET_INSTANCE, &unit, sizeof(unit));
1717			snprintf(mode, sizeof(mode), "wl%d_mode", unit);
1718
1719			/* enable DHCP relay, there should be only one WET i/f */
1720			if (nvram_match(mode, "wet")) {
1721				uint32 ip;
1722				inet_aton(nvram_safe_get("lan_ipaddr"), (struct in_addr *)&ip);
1723				if (wl_iovar_setint(name, "wet_host_ipv4", ip))
1724					perror("wet_host_ipv4");
1725				break;
1726			}
1727		}
1728	}
1729	return 0;
1730}
1731
1732void
1733lan_up(char *lan_ifname)
1734{
1735	/* Install default route to gateway - AP only */
1736	if (nvram_match("router_disable", "1") && nvram_invmatch("lan_gateway", ""))
1737		route_add(lan_ifname, 0, "0.0.0.0", nvram_safe_get("lan_gateway"), "0.0.0.0");
1738
1739	/* Install interface dependent static routes */
1740	add_lan_routes(lan_ifname);
1741
1742	/* Sync time - AP only */
1743	if (nvram_match("router_disable", "1"))
1744		start_ntpc();
1745
1746	/* Enable WET DHCP relay if requested */
1747	if (atoi(nvram_safe_get("dhcp_relay")) == 1)
1748		enable_dhcprelay(lan_ifname);
1749
1750	dprintf("done\n");
1751}
1752
1753void
1754lan_down(char *lan_ifname)
1755{
1756	/* Remove default route to gateway - AP only */
1757	if (nvram_match("router_disable", "1") && nvram_invmatch("lan_gateway", ""))
1758		route_del(lan_ifname, 0, "0.0.0.0", nvram_safe_get("lan_gateway"), "0.0.0.0");
1759
1760	/* Remove interface dependent static routes */
1761	del_lan_routes(lan_ifname);
1762
1763	dprintf("done\n");
1764}
1765
1766int
1767hotplug_net(void)
1768{
1769	char *lan_ifname = nvram_safe_get("lan_ifname");
1770	char *interface, *action;
1771
1772	if (!(interface = getenv("INTERFACE")) ||
1773	    !(action = getenv("ACTION")))
1774		return EINVAL;
1775
1776	if (strncmp(interface, "wds", 3))
1777		return 0;
1778
1779#ifdef LINUX26
1780	if (!strcmp(action, "add")) {
1781#else
1782	if (!strcmp(action, "register")) {
1783#endif
1784		/* Bring up the interface and add to the bridge */
1785		ifconfig(interface, IFUP, NULL, NULL);
1786
1787#ifdef __CONFIG_EMF__
1788		if (nvram_match("emf_enable", "1")) {
1789			eval("emf", "add", "iface", lan_ifname, interface);
1790			emf_mfdb_update(lan_ifname, interface, TRUE);
1791			emf_uffp_update(lan_ifname, interface, TRUE);
1792			emf_rtport_update(lan_ifname, interface, TRUE);
1793		}
1794#endif /* __CONFIG_EMF__ */
1795
1796		/* Bridge WDS interfaces */
1797		if (!strncmp(lan_ifname, "br", 2) &&
1798		    eval("brctl", "addif", lan_ifname, interface, "wait")){
1799		    cprintf("hotplug_net():Adding interface %s\n",interface);
1800		    return 0;
1801		}
1802
1803		/* Inform driver to send up new WDS link event */
1804		if (wl_iovar_setint(interface, "wds_enable", 1)) {
1805			cprintf("%s set wds_enable failed\n", interface);
1806			return 0;
1807		}
1808	}
1809
1810	return 0;
1811}
1812
1813#ifdef __CONFIG_NAT__
1814int
1815wan_ifunit(char *wan_ifname)
1816{
1817	int unit;
1818	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1819
1820	if ((unit = ppp_ifunit(wan_ifname)) >= 0)
1821		return unit;
1822	else {
1823		for (unit = 0; unit < MAX_NVPARSE; unit ++) {
1824			snprintf(prefix, sizeof(prefix), "wan%d_", unit);
1825			if (nvram_match(strcat_r(prefix, "ifname", tmp), wan_ifname) &&
1826			    (nvram_match(strcat_r(prefix, "proto", tmp), "dhcp") ||
1827			     nvram_match(strcat_r(prefix, "proto", tmp), "static")))
1828				return unit;
1829		}
1830	}
1831	return -1;
1832}
1833
1834int
1835preset_wan_routes(char *wan_ifname)
1836{
1837	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1838
1839	/* Figure out nvram variable name prefix for this i/f */
1840	if (wan_prefix(wan_ifname, prefix) < 0)
1841		return -1;
1842
1843	/* Set default route to gateway if specified */
1844	if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1845		route_add(wan_ifname, 0, "0.0.0.0", "0.0.0.0", "0.0.0.0");
1846
1847	/* Install interface dependent static routes */
1848	add_wan_routes(wan_ifname);
1849	return 0;
1850}
1851
1852int
1853wan_primary_ifunit(void)
1854{
1855	int unit;
1856
1857	for (unit = 0; unit < MAX_NVPARSE; unit ++) {
1858		char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1859		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
1860		if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1861			return unit;
1862	}
1863
1864	return 0;
1865}
1866#endif	/* __CONFIG_NAT__ */
1867#if 0//TODO
1868/* To improve EMI per Jack Huang's request */
1869void disable_wlan_g(void)
1870{
1871    char wl1_ifname[32];
1872    strcpy(wl1_ifname, nvram_safe_get("wl1_ifname"));
1873
1874    if (nvram_match("wl1_radio", "0"))
1875    {
1876        eval("wl", "-i", wl1_ifname, "radio", "on");
1877        eval("wl", "-i", wl1_ifname, "up");
1878        eval("wl", "-i", wl1_ifname, "join", "fsadfsa", "imode", "infra");
1879        eval("wl", "-i", wl1_ifname, "txant", "0");
1880        eval("wl", "-i", wl1_ifname, "antdiv", "0");
1881        eval("wl", "-i", wl1_ifname, "out");
1882        eval("wl", "-i", wl1_ifname, "down");
1883        eval("wl", "-i", wl1_ifname, "radio", "off");
1884    }
1885    else
1886    {
1887        eval("wl", "-i", wl1_ifname, "txant", "3");
1888        eval("wl", "-i", wl1_ifname, "antdiv", "3");
1889    }
1890}
1891
1892void enable_wlan_n(void)
1893{
1894    char wl0_ifname[32];
1895    strcpy(wl0_ifname, nvram_safe_get("wl0_ifname"));
1896
1897    /* Set wl interference=2 at all channels to improve throughput */
1898    /* To improve interference on ch. 1 & 11 */
1899    //if (acosNvramConfig_match("wla_channel", "1") ||
1900        //acosNvramConfig_match("wla_channel", "11"))
1901    eval("wl", "-i", wl0_ifname, "interference", "2");
1902    //else
1903        //eval("wl", "-i", wl0_ifname, "interference", "3");
1904
1905    /* These commands are from Kevin Yeh */
1906    eval("wl", "-i", wl0_ifname, "down");
1907    eval("wl", "-i", wl0_ifname, "nphy_antsel", "0x01", "0x01", "0x01", "0x01");
1908    eval("wl", "-i", wl0_ifname, "up");
1909    //eval("wl", "-i", wl0_ifname, "txant", "0");
1910}
1911#endif
1912
1913void stop_wlan(void)
1914{
1915    /* Should store the nvram value in a local variable, instead
1916     *  of keeping just the pointer, since other processes
1917     *  might modify NVRAM at any time.
1918     */
1919#if 0
1920	char *lan_ifname = nvram_safe_get("lan_ifname");
1921	char *wlif = nvram_safe_get("wl0_ifname");
1922#endif
1923	char lan_ifname[32];
1924	char wlif[32];
1925    strcpy(lan_ifname, nvram_safe_get("lan_ifname"));
1926    strcpy(wlif, nvram_safe_get("wl0_ifname"));
1927
1928	eval("wlconf", wlif, "down");
1929	ifconfig(wlif, 0, NULL, NULL);
1930	eval("brctl", "delif", lan_ifname, wlif);
1931
1932    /* Bring down 2nd WLAN i/f */
1933    //wlif = nvram_safe_get("wl1_ifname");
1934    strcpy(wlif, nvram_safe_get("wl1_ifname"));
1935	eval("wlconf", wlif, "down");
1936	ifconfig(wlif, 0, NULL, NULL);
1937	eval("brctl", "delif", lan_ifname, wlif);
1938#if 0//TODO
1939    /* if wireless mode is changed, reload wireless module
1940     * so that the MODE and WIRELESS LED can light correctly.
1941     */
1942    if (nvram_match("wl_mode_changed", "1"))
1943        eval("rmmod", "wl");
1944#endif
1945//#ifdef BUILD_TWC
1946#ifdef MULTIPLE_SSID
1947    if (1)  /* Remove all BSSIDs from LAN */
1948    {
1949        int bssid_num;
1950        for (bssid_num=1; bssid_num<=3; bssid_num++)
1951        {
1952            char if_name[16];
1953            sprintf(if_name, "wl0.%d", bssid_num);
1954            ifconfig(if_name, 0, NULL, NULL);
1955    	    eval("brctl", "delif", lan_ifname, if_name);
1956        }
1957        for (bssid_num=1; bssid_num<=3; bssid_num++)
1958        {
1959            char if_name_5g[16];
1960            sprintf(if_name_5g, "wl1.%d", bssid_num);
1961            ifconfig(if_name_5g, 0, NULL, NULL);
1962    	    eval("brctl", "delif", lan_ifname, if_name_5g);
1963        }
1964    }
1965#endif
1966
1967	return;
1968}
1969
1970void start_wlan(void)
1971{
1972    /* Should store the nvram value in a local variable, instead
1973     *  of keeping just the pointer, since other processes
1974     *  might modify NVRAM at any time.
1975     */
1976	char lan_ifname[32];
1977	char wlif[32];
1978    strcpy(lan_ifname, nvram_safe_get("lan_ifname"));
1979    strcpy(wlif, nvram_safe_get("wl0_ifname"));
1980    char wl1_ifname[32];
1981    char *wl0_obss_coex='1';
1982    int  wl0_obss_coex_val = 1;
1983
1984    strcpy(wl1_ifname, nvram_safe_get("wl1_ifname"));
1985
1986#ifdef CONFIG_RUSSIA_IPTV
1987    char iptv_intf[32];
1988    unsigned char iptv_intf_val = 0x00;
1989    int ru_iptv_en = 0;
1990    int wlan1_en = 0;
1991    int wlan2_en = 0;
1992    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
1993    {
1994        strcpy(iptv_intf, nvram_get(NVRAM_IPTV_INTF));
1995        sscanf(iptv_intf, "0x%02X", &iptv_intf_val);
1996        if (iptv_intf_val & IPTV_WLAN1)
1997            wlan1_en = 1;
1998        else if (iptv_intf_val & IPTV_WLAN2)
1999            wlan2_en = 1;
2000        ru_iptv_en = 1;
2001    }
2002#endif /* CONFIG_RUSSIA_IPTV */
2003    eval("wlconf", wlif, "up");
2004    ifconfig(wlif, IFUP, NULL, NULL);
2005#ifdef CONFIG_RUSSIA_IPTV
2006    if (wlan1_en)
2007	    eval("brctl", "addif", "br1", wlif);
2008    else
2009	    eval("brctl", "addif", lan_ifname, wlif);
2010#else /* CONFIG_RUSSIA_IPTV */
2011	eval("brctl", "addif", lan_ifname, wlif);
2012#endif /* CONFIG_RUSSIA_IPTV */
2013
2014
2015    eval("wlconf", wl1_ifname, "up");
2016    ifconfig(wl1_ifname, IFUP, NULL, NULL);
2017#ifdef CONFIG_RUSSIA_IPTV
2018    if (wlan2_en)
2019	    eval("brctl", "addif", "br1", wl1_ifname);
2020    else
2021        eval("brctl", "addif", lan_ifname, wl1_ifname);
2022#else /* CONFIG_RUSSIA_IPTV */
2023	eval("brctl", "addif", lan_ifname, wl1_ifname);
2024#endif /* CONFIG_RUSSIA_IPTV */
2025
2026    /* For WiFi test case 4.2.41 */
2027    //if(nvram_match("wifi_test", "1"))
2028    wl0_obss_coex=nvram_get("wl0_obss_coex");
2029    eval("wl", "-i", wlif, "obss_coex", wl0_obss_coex);
2030
2031//#ifdef BUILD_TWC
2032#ifdef MULTIPLE_SSID
2033    if (1)      /* Add the additional BSSIDs to LAN */
2034    {
2035        int bssid_num;
2036        for (bssid_num=1; bssid_num<=3; bssid_num++)
2037        {
2038            //char param_name[16];
2039            char param_name[20];
2040            char if_name[16];
2041            sprintf(param_name, "wl0.%d_bss_enabled", bssid_num);
2042            sprintf(if_name, "wl0.%d", bssid_num);
2043            if (nvram_match(param_name, "1"))
2044            {
2045                wl_vif_hwaddr_set(if_name);
2046                ifconfig(if_name, IFUP, NULL, NULL);
2047	            eval("brctl", "addif", lan_ifname, if_name);
2048            }
2049        }
2050        for (bssid_num=1; bssid_num<=3; bssid_num++)
2051        {
2052            char param_name_5g[32];
2053            char if_name_5g[16];
2054            sprintf(param_name_5g, "wl1.%d_bss_enabled", bssid_num);
2055            sprintf(if_name_5g, "wl1.%d", bssid_num);
2056            if (nvram_match(param_name_5g, "1"))
2057            {
2058                wl_vif_hwaddr_set(if_name_5g);
2059                ifconfig(if_name_5g, IFUP, NULL, NULL);
2060	            eval("brctl", "addif", lan_ifname, if_name_5g);
2061            }
2062        }
2063    }
2064#endif
2065
2066
2067    //if(!nvram_match("wifi_test", "1"))
2068        eval("wl", "-i", wl1_ifname, "obss_coex", "0");
2069
2070    eval("wl", "-i", wl1_ifname, "interference", "4");
2071
2072    {
2073        int s;
2074        struct ifreq ifr;
2075        unsigned char hwaddr[ETHER_ADDR_LEN] = "";
2076
2077        ether_atoe(nvram_safe_get("lan_hwaddr"), hwaddr);
2078        if (memcmp(hwaddr, "\0\0\0\0\0\0", ETHER_ADDR_LEN) &&
2079            (s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
2080            strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
2081            ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
2082            memcpy(ifr.ifr_hwaddr.sa_data, hwaddr, ETHER_ADDR_LEN);
2083            ioctl(s, SIOCSIFHWADDR, &ifr);
2084            close(s);
2085        }
2086    }
2087
2088	return;
2089}
2090