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