1/*
2 * Network services
3 *
4 * Copyright 2004, 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.1.1.1 2008/10/15 03:28:35 james26_jang 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>
31typedef u_int64_t u64;
32typedef u_int32_t u32;
33typedef u_int16_t u16;
34typedef u_int8_t u8;
35#include <linux/sockios.h>
36#include <linux/ethtool.h>
37#include <bcmnvram.h>
38#include <netconf.h>
39#include <shutils.h>
40#include <wlutils.h>
41#include <nvparse.h>
42#include <rc.h>
43#include <bcmutils.h>
44#include <etsockio.h>
45#include <bcmparams.h>
46
47static int
48add_routes(char *prefix, char *var, char *ifname)
49{
50	char word[80], *next;
51	char *ipaddr, *netmask, *gateway, *metric;
52	char tmp[100];
53
54	foreach(word, nvram_safe_get(strcat_r(prefix, var, tmp)), next) {
55
56		netmask = word;
57		ipaddr = strsep(&netmask, ":");
58		if (!ipaddr || !netmask)
59			continue;
60		gateway = netmask;
61		netmask = strsep(&gateway, ":");
62		if (!netmask || !gateway)
63			continue;
64		metric = gateway;
65		gateway = strsep(&metric, ":");
66		if (!gateway || !metric)
67			continue;
68
69		dprintf("\n\n\nadd %s %d %s %s %s\n\n\n", ifname, atoi(metric), ipaddr, gateway, netmask);
70
71		route_add(ifname, atoi(metric) + 1, ipaddr, gateway, netmask);
72	}
73
74	return 0;
75}
76
77static int
78del_routes(char *prefix, char *var, char *ifname)
79{
80	char word[80], *next;
81	char *ipaddr, *netmask, *gateway, *metric;
82	char tmp[100];
83
84	foreach(word, nvram_safe_get(strcat_r(prefix, var, tmp)), next) {
85		dprintf("add %s\n", word);
86
87		netmask = word;
88		ipaddr = strsep(&netmask, ":");
89		if (!ipaddr || !netmask)
90			continue;
91		gateway = netmask;
92		netmask = strsep(&gateway, ":");
93		if (!netmask || !gateway)
94			continue;
95		metric = gateway;
96		gateway = strsep(&metric, ":");
97		if (!gateway || !metric)
98			continue;
99
100		dprintf("add %s\n", ifname);
101
102		route_del(ifname, atoi(metric) + 1, ipaddr, gateway, netmask);
103	}
104
105	return 0;
106}
107
108static int
109add_lan_routes(char *lan_ifname)
110{
111	return add_routes("lan_", "route", lan_ifname);
112}
113
114static int
115del_lan_routes(char *lan_ifname)
116{
117	return del_routes("lan_", "route", lan_ifname);
118}
119
120void
121start_lan(void)
122{
123	char *lan_ifname = nvram_safe_get("lan_ifname");
124	char br0_ifnames[255];
125	char name[80], *next;
126	char tmpstr[48];
127	int i, j;
128	int s;
129	struct ifreq ifr;
130
131	dprintf("%s\n", lan_ifname);
132
133#ifdef GUEST_ACCOUNT
134	memset(br0_ifnames,0,sizeof(br0_ifnames));
135
136	nvram_unset("unbridged_ifnames");
137	nvram_unset("br0_ifnames");
138
139	/* If we're a travel router... then we need to make sure we get
140		 the primary wireless interface up before trying to attach slave
141		 interface(s) to the bridge */
142#endif
143
144#ifdef URE
145	if(nvram_match("ure_disable", "0"))
146	{
147		eval("wlconf", nvram_get("wan0_ifname"), "up");
148	}
149#endif
150
151 	/* Bring up bridged interfaces */
152	if (strncmp(lan_ifname, "br", 2) == 0) {
153		eval("brctl", "addbr", lan_ifname);
154		eval("brctl", "setfd", lan_ifname, "0");
155		if (nvram_match("router_disable", "1") || nvram_match("lan_stp", "0"))
156			eval("brctl", "stp", lan_ifname, "dis");
157#ifdef ASUS_EXT
158		foreach(name, nvram_safe_get("lan_ifnames_t"), next) {
159#else
160		foreach(name, nvram_safe_get("lan_ifnames"), next) {
161#endif
162			/* Bring up interface */
163			ifconfig(name, IFUP, NULL, NULL);
164			/* Set the logical bridge address to that of the first interface */
165			if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
166				continue;
167			strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
168			if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0 &&
169			    memcmp(ifr.ifr_hwaddr.sa_data, "\0\0\0\0\0\0", ETHER_ADDR_LEN) == 0) {
170				strncpy(ifr.ifr_name, name, IFNAMSIZ);
171				if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {
172					strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
173					ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
174					ioctl(s, SIOCSIFHWADDR, &ifr);
175				}
176			}
177			close(s);
178			/* If not a wl i/f then simply add it to the bridge */
179			if (eval("wlconf", name, "up"))
180			{
181#ifdef RT2400_SUPPORT
182				if (strcmp(name, "eth2")==0)
183				{
184					// added by Joey for WL500b + WL127
185					if (nvram_match("wl_channel", "0"))
186						nvram_set("wl_channel", "6");
187
188					sprintf(tmpstr, "mac_address=%s", nvram_safe_get("et0macaddr"));
189					eval("insmod","rt2400.o",tmpstr);
190					eval("brctl","addif",lan_ifname,"ra0");
191					ifconfig("ra0",IFUP,NULL,NULL);
192					nvram_set("nobr","1");
193
194					j = atoi(nvram_safe_get("wl_wdsnum_x"));
195					for(i=1;i<=j;i++)
196					{
197						sprintf(tmpstr, "ra%d", i);							ifconfig(tmpstr, IFUP, NULL, NULL);
198						eval("brctl","addif",lan_ifname,tmpstr);
199					}
200				}
201				else
202#endif
203
204#ifdef GUEST_ACCOUNT
205				{
206					if (eval("brctl", "addif", lan_ifname, name))
207						perror("brctl");
208					else{
209						char buf[255],*ptr;
210						ptr = nvram_get("br0_ifnames");
211						if (ptr)
212							snprintf(buf,sizeof(buf),"%s %s",ptr,name);
213						else
214							strncpy(buf,name,sizeof(buf));
215						nvram_set("br0_ifnames",buf);
216					}
217				}
218#else
219				eval("brctl", "addif", lan_ifname, name);
220#endif
221
222			}
223			else
224			{
225#ifdef GUEST_ACCOUNT
226				char wl_guest[] = "wlXXXXXXXXXX_guest";
227				char wl_vifs[]= "wlXXXXXXXXXX_vifs";
228				char mode[] = "wlXXXXXXXXXX_mode";
229				char *vifs;
230#endif
231
232				/* get the instance number of the wl i/f */
233				char wl_name[] = "wlXXXXXXXXXX_mode";
234				int unit;
235#ifdef ASUS_EXT
236				sync_mac(name, nvram_safe_get("et0macaddr"));
237#endif
238				wl_ioctl(name, WLC_GET_INSTANCE, &unit, sizeof(unit));
239				snprintf(wl_name, sizeof(wl_name), "wl%d_mode", unit);
240
241#ifdef GUEST_ACCOUNT
242				snprintf(wl_guest, sizeof(wl_guest), "wl%d_guest", unit);
243				snprintf(wl_vifs, sizeof(wl_vifs), "wl%d_vifs", unit);
244
245				/* Multi-SSID specific configuration */
246				/* Virtual interfaces are created with  the master interface
247				   by wlconf() . Only copy those that have wlX.Y_guest set*/
248
249				vifs = nvram_get(wl_vifs);
250
251				if (vifs){
252					char buf[255];
253					char name[32];
254					char vif_guest[32];
255					char *ptr=NULL,*next=NULL;
256
257					memset(buf,0,sizeof(buf));
258
259					ptr = nvram_get("unbridged_ifnames");
260
261					if (ptr) snprintf(buf,sizeof(buf),"%s",ptr);
262
263					/*Loop thru wlX_vifs to get the virtual interfaces
264				          wlX.Y_guest must be set for IP to configure it*/
265					foreach(name,vifs,next){
266						snprintf(vif_guest,sizeof(vif_guest),"%s_guest",name);
267						cprintf("vif_guest=%s\n", vif_guest);
268						if (nvram_match(vif_guest,"1")){
269							if(*buf)
270								snprintf(buf,sizeof(buf),"%s %s",buf,name);
271							else
272								strncpy(buf,name,sizeof(buf));
273						}
274					}
275
276					if (*buf) nvram_set("unbridged_ifnames",buf);
277				}
278#endif
279				/* Receive all multicast frames in WET mode */
280				if (nvram_match(wl_name, "wet"))
281				{
282					ifconfig(name, IFUP | IFF_ALLMULTI, NULL, NULL);
283#ifdef GUEST_ACCOUNT
284					/* Enable host DHCP relay */
285					if (nvram_match("lan_dhcp", "1"))
286						wl_iovar_set(name, "wet_host_mac", ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
287#endif
288				}
289
290				/* Do not attach the main wl i/f if in wds mode */
291#ifdef GUEST_ACCOUNT
292				if ( !nvram_match(mode, "wds") && !nvram_match(wl_guest, "1")){
293					char buf[255],*ptr;
294
295					eval("brctl", "addif", lan_ifname, name);
296
297					ptr = nvram_get("br0_ifnames");
298					if (ptr)
299						snprintf(buf,sizeof(buf),"%s %s",ptr,name);
300					else
301						strncpy(buf,name,sizeof(buf));
302					nvram_set("br0_ifnames",buf);
303				}
304#else
305				if (nvram_invmatch(wl_name, "wds"))
306					eval("brctl", "addif",lan_ifname,name);
307#endif
308			}
309		}
310	}
311	/* specific non-bridged lan i/f */
312	else if (strcmp(lan_ifname, "")) {
313		/* Bring up interface */
314		ifconfig(lan_ifname, IFUP, NULL, NULL);
315		/* config wireless i/f */
316		if (!eval("wlconf", lan_ifname, "up")) {
317			char tmp[100], prefix[] = "wanXXXXXXXXXX_";
318			int unit;
319			/* get the instance number of the wl i/f */
320			wl_ioctl(lan_ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
321			snprintf(prefix, sizeof(prefix), "wl%d_", unit);
322			/* Receive all multicast frames in WET mode */
323			if (nvram_match(strcat_r(prefix, "mode", tmp), "wet"))
324				ifconfig(lan_ifname, IFUP | IFF_ALLMULTI, NULL, NULL);
325		}
326	}
327#ifdef GUEST_ACCOUNT
328	/* build unbridged ifnames NVRAM var from wl_guest list */
329	foreach(name, nvram_safe_get("lan_ifnames"), next) {
330
331		char wl_guest[] = "wlXXXXXXXXXX_guest";
332		int unit;
333
334		if (!eval("wlconf", name, "up")) {
335			wl_ioctl(name, WLC_GET_INSTANCE, &unit, sizeof(unit));
336			snprintf(wl_guest, sizeof(wl_guest), "wl%d_guest", unit);
337
338			if (nvram_match(wl_guest,"1")){
339				char buf[255],*ptr;
340
341				ptr = nvram_get("unbridged_ifnames");
342				if (ptr)
343					snprintf(buf,sizeof(buf),"%s %s",ptr,name);
344				else
345					strncpy(buf,name,sizeof(buf));
346
347				nvram_set("unbridged_ifnames",buf);
348			}
349		}
350	}
351#endif
352	/* Get current LAN hardware address */
353	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
354		char eabuf[32];
355		strncpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
356		if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0)
357			nvram_set("lan_hwaddr", ether_etoa(ifr.ifr_hwaddr.sa_data, eabuf));
358		close(s);
359	}
360
361#ifdef WPA2_WMM
362	/* Set QoS mode */
363	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
364		int i, qos;
365		caddr_t ifrdata;
366		struct ethtool_drvinfo info;
367
368		qos = (strcmp(nvram_safe_get("wl_wme"), "on")) ? 0 : 1;
369		for (i = 1; i <= DEV_NUMIFS; i ++) {
370			ifr.ifr_ifindex = i;
371			if (ioctl(s, SIOCGIFNAME, &ifr))
372				continue;
373			if (ioctl(s, SIOCGIFHWADDR, &ifr))
374				continue;
375			if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
376				continue;
377			/* get flags */
378			if (ioctl(s, SIOCGIFFLAGS, &ifr))
379				continue;
380			/* if up(wan not up yet at this point) */
381			if (ifr.ifr_flags & IFF_UP) {
382				ifrdata = ifr.ifr_data;
383				memset(&info, 0, sizeof(info));
384				info.cmd = ETHTOOL_GDRVINFO;
385				ifr.ifr_data = (caddr_t)&info;
386				if (ioctl(s, SIOCETHTOOL, &ifr) >= 0) {
387					/* currently only need to set QoS to et devices */
388					if (!strncmp(info.driver, "et", 2)) {
389						ifr.ifr_data = (caddr_t)&qos;
390						ioctl(s, SIOCSETCQOS, &ifr);
391					}
392				}
393				ifr.ifr_data = ifrdata;
394			}
395		}
396	}
397#endif
398
399#ifdef ASUS_EXT
400#ifndef FLASH2M
401	/*
402	* Configure DHCP connection. The DHCP client will run
403	* 'udhcpc bound'/'udhcpc deconfig' upon finishing IP address
404	* renew and release.
405	*/
406	if (nvram_match("router_disable", "1"))
407	{
408		if (nvram_match("lan_proto_x", "1"))
409		{
410			char *dhcp_argv[] = { "udhcpc",
411					      "-i", lan_ifname,
412					      "-p", "/var/run/udhcpc_lan.pid",
413					      "-s", "/tmp/landhcpc",
414					      NULL
415			};
416			pid_t pid;
417
418
419			/* Bring up and configure LAN interface */
420			ifconfig(lan_ifname, IFUP,
421		 		nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
422
423			symlink("/sbin/rc", "/tmp/landhcpc");
424
425			/* Start dhcp daemon */
426			_eval(dhcp_argv, NULL, 0, &pid);
427		}
428		else
429		{
430			/* Bring up and configure LAN interface */
431			ifconfig(lan_ifname, IFUP,
432		 		nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
433			lan_up(lan_ifname);
434
435			update_lan_status(1);
436		}
437	}
438	else
439#endif // end of FLASH2M
440	{
441		/* Bring up and configure LAN interface */
442		ifconfig(lan_ifname, IFUP,
443		 	nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
444		/* Install lan specific static routes */
445		add_lan_routes(lan_ifname);
446
447		update_lan_status(1);
448	}
449#else
450	/* Bring up and configure LAN interface */
451	ifconfig(lan_ifname, IFUP,
452		 nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
453
454	/* Install lan specific static routes */
455	add_lan_routes(lan_ifname);
456#endif
457
458#ifdef GUEST_ACCOUNT
459	/* Bring up unbridged LAN interfaces (if they exist)*/
460	{
461	char *interfaces,*ifname, *ptr;
462	char word[64], *next;
463	int index =1 ;
464
465	interfaces = nvram_get("unbridged_ifnames");
466	if (interfaces)
467		foreach(word,interfaces,next){
468
469		 	char interface[32], mask[32];
470		 	int s;
471
472		 	ptr=word;
473			ifname = word;
474			index =  get_ipconfig_index(ifname);
475
476			if ( index < 0) {
477				cprintf("Cannot find index for interface:%s\n",ifname);
478				continue;
479			}
480
481			snprintf(interface,sizeof(interface),"lan%d_ipaddr",index);
482		 	snprintf(mask,sizeof(mask),"lan%d_netmask",index);
483		 	ifconfig(ifname, IFUP,nvram_safe_get(interface), nvram_safe_get(mask));
484
485		 	/* Get Ethernet hardware address. Note this value NOT is committed to NVRAM */
486		 	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
487		 		struct ifreq ifr;
488				char macaddr[]="00:00:00:00:00:00";
489				char mac[32];
490
491				memset(&ifr,0,sizeof(ifr));
492				strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
493				if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0){
494					ether_etoa(ifr.ifr_hwaddr.sa_data, macaddr);
495					snprintf(mac,sizeof(mac),"lan%d_hwaddr",index);
496					nvram_set(mac,macaddr);
497				}
498				close(s);
499			}
500
501		}
502	}
503#endif
504
505#ifndef ASUS_EXT
506	/* Start syslogd if either log_ipaddr or log_ram_enable is set */
507	if (nvram_invmatch("log_ipaddr", "") || nvram_match("log_ram_enable", "1")) {
508		char *argv[] = {
509			"syslogd",
510			NULL, 		/* -C */
511			NULL, NULL,	/* -R host */
512			NULL
513		};
514		int pid;
515		int argc = 1;
516
517		if (nvram_match("log_ram_enable", "1")) {
518			argv[argc++] = "-C";
519		}
520		else if (!nvram_match("log_ram_enable", "0")) {
521			nvram_set("log_ram_enable", "0");
522		}
523
524		if (nvram_invmatch("log_ipaddr", "")) {
525			argv[argc++] = "-R";
526			argv[argc++] = nvram_get("log_ipaddr");
527		}
528
529		_eval(argv, NULL, 0, &pid);
530	}
531#endif
532
533	dprintf("%s %s\n",
534		nvram_safe_get("lan_ipaddr"),
535		nvram_safe_get("lan_netmask"));
536}
537
538void
539stop_lan(void)
540{
541	char *lan_ifname = nvram_safe_get("lan_ifname");
542	char name[80], *next;
543
544	dprintf("%s\n", lan_ifname);
545
546	/* Stop the syslogd daemon */
547	eval("killall", "syslogd");
548
549	/* Remove static routes */
550	del_lan_routes(lan_ifname);
551
552	/* Bring down LAN interface */
553	ifconfig(lan_ifname, 0, NULL, NULL);
554
555	/* Bring down bridged interfaces */
556	if (strncmp(lan_ifname, "br", 2) == 0) {
557#ifdef ASUS_EXT
558		foreach(name, nvram_safe_get("lan_ifnames_t"), next) {
559#else
560		foreach(name, nvram_safe_get("lan_ifnames"), next) {
561#endif
562			eval("wlconf", name, "down");
563			ifconfig(name, 0, NULL, NULL);
564			eval("brctl", "delif", lan_ifname, name);
565		}
566		eval("brctl", "delbr", lan_ifname);
567	}
568	/* Bring down specific interface */
569	else if (strcmp(lan_ifname, ""))
570		eval("wlconf", lan_ifname, "down");
571
572	dprintf("done\n");
573}
574
575static int
576wan_prefix(char *ifname, char *prefix)
577{
578	int unit;
579
580	if ((unit = wan_ifunit(ifname)) < 0)
581		return -1;
582
583	sprintf(prefix, "wan%d_", unit);
584	return 0;
585}
586
587static int
588add_wan_routes(char *wan_ifname)
589{
590	char prefix[] = "wanXXXXXXXXXX_";
591
592	/* Figure out nvram variable name prefix for this i/f */
593	if (wan_prefix(wan_ifname, prefix) < 0)
594		return -1;
595
596	return add_routes(prefix, "route", wan_ifname);
597}
598
599static int
600del_wan_routes(char *wan_ifname)
601{
602	char prefix[] = "wanXXXXXXXXXX_";
603
604	/* Figure out nvram variable name prefix for this i/f */
605	if (wan_prefix(wan_ifname, prefix) < 0)
606		return -1;
607
608	return del_routes(prefix, "route", wan_ifname);
609}
610
611int
612wan_valid(char *ifname)
613{
614	char name[80], *next;
615
616	foreach(name, nvram_safe_get("wan_ifnames"), next)
617		if (ifname && !strcmp(ifname, name))
618			return 1;
619
620#ifdef WIRELESS_WAN
621	if (nvram_invmatch("wl_mode_ex", "ap")) {
622		return nvram_match("wl0_ifname", ifname);
623	}
624#endif
625	return 0;
626}
627
628void
629start_wan(void)
630{
631	char *wan_ifname;
632	char *wan_proto;
633	int unit;
634	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
635	char eabuf[32];
636	int s;
637	struct ifreq ifr;
638	pid_t pid;
639
640	/* check if we need to setup WAN */
641	if (nvram_match("router_disable", "1")
642#ifdef BTN_SETUP
643		|| is_ots()
644#endif
645)
646		return;
647
648#ifdef ASUS_EXT
649	update_wan_status(0);
650	/* start connection independent firewall */
651	start_firewall();
652#else
653	/* start connection independent firewall */
654	start_firewall();
655#endif
656
657	/* Create links */
658	mkdir("/tmp/ppp", 0777);
659	mkdir("/tmp/ppp/peers", 0777);
660	symlink("/sbin/rc", "/tmp/ppp/ip-up");
661	symlink("/sbin/rc", "/tmp/ppp/ip-down");
662	symlink("/sbin/rc", "/tmp/udhcpc");
663
664	//symlink("/dev/null", "/tmp/ppp/connect-errors");
665
666	/* Start each configured and enabled wan connection and its undelying i/f */
667	for (unit = 0; unit < MAX_NVPARSE; unit ++)
668	{
669#ifdef ASUS_EXT // Only multiple pppoe is allowed
670		if (unit>0 && nvram_invmatch("wan_proto", "pppoe")) break;
671#endif
672
673		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
674
675		/* make sure the connection exists and is enabled */
676		wan_ifname = nvram_get(strcat_r(prefix, "ifname", tmp));
677		if (!wan_ifname)
678			continue;
679		wan_proto = nvram_get(strcat_r(prefix, "proto", tmp));
680		if (!wan_proto || !strcmp(wan_proto, "disabled"))
681			continue;
682
683		/* disable the connection if the i/f is not in wan_ifnames */
684		if (!wan_valid(wan_ifname)) {
685			nvram_set(strcat_r(prefix, "proto", tmp), "disabled");
686			continue;
687		}
688
689		dprintf("%s %s\n\n\n\n\n", wan_ifname, wan_proto);
690
691		/* Set i/f hardware address before bringing it up */
692		if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
693			continue;
694
695		strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
696
697		/* Since WAN interface may be already turned up (by vlan.c),
698		   if WAN hardware address is specified (and different than the current one),
699		   we need to make it down for synchronizing hwaddr. */
700		if (ioctl(s, SIOCGIFHWADDR, &ifr)) {
701			close(s);
702			continue;
703		}
704
705		ether_atoe(nvram_safe_get(strcat_r(prefix, "hwaddr", tmp)), eabuf);
706		if (bcmp(eabuf, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN))
707		{
708			/* current hardware address is different than user specified */
709			ifconfig(wan_ifname, 0, NULL, NULL);
710		}
711
712		/* Configure i/f only once, specially for wireless i/f shared by multiple connections */
713		if (ioctl(s, SIOCGIFFLAGS, &ifr)) {
714			close(s);
715			continue;
716		}
717		if (!(ifr.ifr_flags & IFF_UP)) {
718			/* Sync connection nvram address and i/f hardware address */
719			memset(ifr.ifr_hwaddr.sa_data, 0, ETHER_ADDR_LEN);
720
721			if (!nvram_invmatch(strcat_r(prefix, "hwaddr", tmp), "") ||
722			    !ether_atoe(nvram_safe_get(strcat_r(prefix, "hwaddr", tmp)), ifr.ifr_hwaddr.sa_data) ||
723			    !memcmp(ifr.ifr_hwaddr.sa_data, "\0\0\0\0\0\0", ETHER_ADDR_LEN)) {
724				if (ioctl(s, SIOCGIFHWADDR, &ifr)) {
725					close(s);
726					continue;
727				}
728				nvram_set(strcat_r(prefix, "hwaddr", tmp), ether_etoa(ifr.ifr_hwaddr.sa_data, eabuf));
729			}
730			else {
731				ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
732				ioctl(s, SIOCSIFHWADDR, &ifr);
733			}
734
735			/* Bring up i/f */
736			ifconfig(wan_ifname, IFUP, NULL, NULL);
737
738#ifdef URE
739			/* do wireless specific config */
740			if(nvram_match("ure_disable", "1"))
741			{
742				eval("wlconf", wan_ifname, "up");
743			}
744#else
745			/* do wireless specific config */
746			eval("wlconf", wan_ifname, "up");
747#endif
748		}
749
750		close(s);
751
752
753#ifdef ASUS_EXT
754		if (unit==0)
755		{
756			FILE *fp;
757
758			setup_ethernet(nvram_safe_get("wan_ifname"));
759			start_pppoe_relay(nvram_safe_get("wan_ifname"));
760
761
762			/* Enable Forwarding */
763			if ((fp = fopen("/proc/sys/net/ipv4/ip_forward", "r+"))) 			{
764				fputc('1', fp);
765				fclose(fp);
766			} else
767			{
768				perror("/proc/sys/net/ipv4/ip_forward");
769			}
770		}
771
772		/*
773		* Configure PPPoE connection. The PPPoE client will run
774		* ip-up/ip-down scripts upon link's connect/disconnect.
775		*/
776		if (strcmp(wan_proto, "bigpond")==0)
777        {
778//                printf("!!!Start CDMA!!!\n");
779                start_cdma();
780                update_wan_status(0);
781        }
782
783#ifdef RPPPPOE
784		else if (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp"))
785		{
786
787			int demand = atoi(nvram_safe_get(strcat_r(prefix, "pppoe_idletime", tmp)));
788
789			/* update demand option */
790			nvram_set(strcat_r(prefix, "pppoe_demand", tmp), demand ? "1" : "0");
791			/* Bring up  WAN interface */
792			if (strcmp(wan_proto, "pptp") == 0) {
793				ifconfig(wan_ifname, IFUP,
794					nvram_safe_get("wanx_ipaddr"),
795					nvram_safe_get("wanx_netmask"));
796
797				/* add pptp server route */
798				if (nvram_invmatch("wan_heartbeat_x", "")) {
799					route_add(wan_ifname, 0, nvram_safe_get("wan_heartbeat_x"),
800						nvram_get(strcat_r(prefix, "pppoe_gateway", tmp)), "255.255.255.255");
801				} else {
802					route_add(wan_ifname, 0, nvram_safe_get(strcat_r(prefix, "pppoe_gateway", tmp)),
803						NULL, "255.255.255.255");
804				}
805
806		 	} else {
807		 		/* do not use safe_get here, values are optional */
808				ifconfig(wan_ifname, IFUP,
809					nvram_get("wan_ipaddr"),
810					nvram_get("wan_netmask"));
811		 	}
812
813		 	/* setup static wan routes via physical device */
814			add_routes("wan_", "route", wan_ifname);
815
816			start_pppd(prefix);
817
818			/* ppp interface name is referenced from this point on */
819			wan_ifname = nvram_safe_get(strcat_r(prefix, "pppoe_ifname", tmp));
820
821			/* Pretend that the WAN interface is up */
822			if (nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1"))
823			{
824				int timeout = 5;
825				/* Wait for pppx to be created */
826				while (ifconfig(wan_ifname, IFUP, NULL, NULL) && timeout--)
827					sleep(1);
828
829				/* Retrieve IP info */
830				if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
831					continue;
832				strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
833
834				/* Set temporary IP address */
835				if (ioctl(s, SIOCGIFADDR, &ifr))
836					perror(wan_ifname);
837
838				nvram_set(strcat_r(prefix, "ipaddr", tmp), inet_ntoa(sin_addr(&ifr.ifr_addr)));
839				nvram_set(strcat_r(prefix, "netmask", tmp), "255.255.255.255");
840
841				/* Set temporary P-t-P address */
842				if (ioctl(s, SIOCGIFDSTADDR, &ifr))
843					perror(wan_ifname);
844				nvram_set(strcat_r(prefix, "gateway", tmp), inet_ntoa(sin_addr(&ifr.ifr_dstaddr)));
845
846				close(s);
847
848				/*
849				* Preset routes so that traffic can be sent to proper pppx even before
850				* the link is brought up.
851				*/
852				preset_wan_routes(wan_ifname);
853			}
854
855		}
856#else
857		if (strcmp(wan_proto, "pppoe") == 0) {
858			char *pppoe_argv[] = { "pppoecd",
859					       nvram_safe_get(strcat_r(prefix, "ifname", tmp)),
860					       "-u", nvram_safe_get(strcat_r(prefix, "pppoe_username", tmp)),
861					       "-p", nvram_safe_get(strcat_r(prefix, "pppoe_passwd", tmp)),
862					       "-r", nvram_safe_get(strcat_r(prefix, "pppoe_mru", tmp)),
863					       "-t", nvram_safe_get(strcat_r(prefix, "pppoe_mtu", tmp)),
864					       "-i", nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1") ?
865					       		nvram_safe_get(strcat_r(prefix, "pppoe_idletime", tmp)) : "0",
866#ifdef ASUS_EXT
867						NULL, NULL,
868						NULL, NULL,
869						NULL, NULL,
870#endif
871					       NULL, NULL,	/* pppoe_service */
872					       NULL, NULL,	/* pppoe_ac */
873					       NULL,		/* pppoe_keepalive */
874					       NULL, NULL,	/* ppp unit requested */
875					       NULL
876			}, **arg;
877			int timeout = 5;
878			char pppunit[] = "XXXXXXXXXXXX";
879
880			/* Add optional arguments */
881
882			for (arg = pppoe_argv; *arg; arg++);
883
884#ifdef ASUS_EXT
885			if (nvram_invmatch(strcat_r(prefix, "pppoe_idletime", tmp), "0"))
886			{
887				*arg++ = "-I";
888				*arg++ = "30";
889
890				*arg++ = "-T";
891				*arg++ = "9";
892
893				*arg++ = "-N";
894				*arg++ = "10";
895			}
896
897			if (nvram_invmatch(strcat_r(prefix, "pppoe_txonly_x", tmp), "0")) {
898				*arg++ = "-o";
899			}
900#endif
901			if (nvram_invmatch(strcat_r(prefix, "pppoe_service", tmp), "")) {
902				*arg++ = "-s";
903				*arg++ = nvram_safe_get(strcat_r(prefix, "pppoe_service", tmp));
904			}
905			if (nvram_invmatch(strcat_r(prefix, "pppoe_ac", tmp), "")) {
906				*arg++ = "-a";
907				*arg++ = nvram_safe_get(strcat_r(prefix, "pppoe_ac", tmp));
908			}
909
910#ifndef ASUS_EXT	// keep alive anyway
911			if (nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1") ||
912			    nvram_match(strcat_r(prefix, "pppoe_keepalive", tmp), "1"))
913#endif
914				*arg++ = "-k";
915			snprintf(pppunit, sizeof(pppunit), "%d", unit);
916			*arg++ = "-U";
917			*arg++ = pppunit;
918
919			/* launch pppoe client daemon */
920			_eval(pppoe_argv, NULL, 0, &pid);
921
922			/* ppp interface name is referenced from this point on */
923			wan_ifname = nvram_safe_get(strcat_r(prefix, "pppoe_ifname", tmp));
924
925			/* Pretend that the WAN interface is up */
926			if (nvram_match(strcat_r(prefix, "pppoe_demand", tmp), "1")) {
927				/* Wait for pppx to be created */
928				while (ifconfig(wan_ifname, IFUP, NULL, NULL) && timeout--)
929					sleep(1);
930
931				/* Retrieve IP info */
932				if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
933					continue;
934				strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
935
936				/* Set temporary IP address */
937				if (ioctl(s, SIOCGIFADDR, &ifr))
938					perror(wan_ifname);
939				nvram_set(strcat_r(prefix, "ipaddr", tmp), inet_ntoa(sin_addr(&ifr.ifr_addr)));
940				nvram_set(strcat_r(prefix, "netmask", tmp), "255.255.255.255");
941
942				/* Set temporary P-t-P address */
943				if (ioctl(s, SIOCGIFDSTADDR, &ifr))
944					perror(wan_ifname);
945				nvram_set(strcat_r(prefix, "gateway", tmp), inet_ntoa(sin_addr(&ifr.ifr_dstaddr)));
946
947				close(s);
948
949				/*
950				* Preset routes so that traffic can be sent to proper pppx even before
951				* the link is brought up.
952				*/
953
954				preset_wan_routes(wan_ifname);
955			}
956#ifdef ASUS_EXT
957			nvram_set("wan_ifname_t", wan_ifname);
958#endif
959		}
960#endif // FLASH2M
961#endif
962		/*
963		* Configure DHCP connection. The DHCP client will run
964		* 'udhcpc bound'/'udhcpc deconfig' upon finishing IP address
965		* renew and release.
966		*/
967
968		else if (strcmp(wan_proto, "dhcp") == 0 ||
969			 strcmp(wan_proto, "bigpond") == 0 ){
970			char *wan_hostname = nvram_get(strcat_r(prefix, "hostname", tmp));
971			char *dhcp_argv[] = { "udhcpc",
972					      "-i", wan_ifname,
973					      "-p", (sprintf(tmp, "/var/run/udhcpc%d.pid", unit), tmp),
974					      "-s", "/tmp/udhcpc",
975					      wan_hostname && *wan_hostname ? "-H" : NULL,
976					      wan_hostname && *wan_hostname ? wan_hostname : NULL,
977					      NULL
978			};
979			/* Start dhcp daemon */
980			_eval(dhcp_argv, NULL, 0, &pid);
981#ifdef ASUS_EXT
982			wanmessage("Can not get IP from server");
983			nvram_set("wan_ifname_t", wan_ifname);
984#endif
985		}
986		/* Configure static IP connection. */
987		else if (strcmp(wan_proto, "static") == 0) {
988			/* Assign static IP address to i/f */
989			ifconfig(wan_ifname, IFUP,
990				 nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
991				 nvram_safe_get(strcat_r(prefix, "netmask", tmp)));
992			/* We are done configuration */
993			wan_up(wan_ifname);
994#ifdef ASUS_EXT
995			nvram_set("wan_ifname_t", wan_ifname);
996#endif
997		}
998#if 0
999	else if (strcmp(wan_proto, "cdma")==0)
1000        {
1001//                printf("!!!Start CDMA!!!\n");
1002                start_cdma();
1003                update_wan_status(0);
1004        }
1005#endif
1006
1007#ifndef ASUS_EXT
1008		/* Start connection dependent firewall */
1009		start_firewall2(wan_ifname);
1010#endif
1011
1012		dprintf("%s %s\n",
1013			nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
1014			nvram_safe_get(strcat_r(prefix, "netmask", tmp)));
1015	}
1016
1017	/* Report stats */
1018	if (nvram_invmatch("stats_server", "")) {
1019		char *stats_argv[] = { "stats", nvram_get("stats_server"), NULL };
1020		_eval(stats_argv, NULL, 5, NULL);
1021	}
1022}
1023
1024void
1025stop_wan(void)
1026{
1027	char name[80], *next, signal[] = "XXXX";
1028
1029	eval("killall", "stats");
1030	eval("killall", "ntpclient");
1031
1032	/* Shutdown and kill all possible tasks */
1033	eval("killall", "ip-up");
1034	eval("killall", "ip-down");
1035	snprintf(signal, sizeof(signal), "-%d", SIGHUP);
1036	eval("killall", signal, "pppoecd");
1037	eval("killall", signal, "pppd");
1038	eval("killall", "pppoecd");
1039	eval("killall", "pppd");
1040	snprintf(signal, sizeof(signal), "-%d", SIGUSR2);
1041	eval("killall", signal, "udhcpc");
1042	eval("killall", "udhcpc");
1043
1044	/* Bring down WAN interfaces */
1045	foreach(name, nvram_safe_get("wan_ifnames"), next)
1046	{
1047		ifconfig(name, 0, NULL, NULL);
1048	}
1049
1050	/* Remove dynamically created links */
1051	unlink("/tmp/udhcpc");
1052
1053	unlink("/tmp/ppp/ip-up");
1054	unlink("/tmp/ppp/ip-down");
1055	unlink("/tmp/ppp/options");
1056	rmdir("/tmp/ppp");
1057
1058#ifdef ASUS_EXT
1059	update_wan_status(0);
1060#endif
1061
1062	dprintf("done\n");
1063}
1064
1065void
1066stop_wan2(void)
1067{
1068	char name[80], *next, signal[] = "XXXX";
1069
1070	eval("killall", "stats");
1071	eval("killall", "ntpclient");
1072
1073	/* Shutdown and kill all possible tasks */
1074	eval("killall", "ip-up");
1075	eval("killall", "ip-down");
1076	snprintf(signal, sizeof(signal), "-%d", SIGHUP);
1077	eval("killall", signal, "pppoecd");
1078	eval("killall", signal, "pppd");
1079	eval("killall", "pppoecd");
1080	eval("killall", "pppd");
1081
1082	snprintf(signal, sizeof(signal), "-%d", SIGUSR2);
1083	eval("killall", signal, "udhcpc");
1084	eval("killall", "udhcpc");
1085
1086	/* Remove dynamically created links */
1087	unlink("/tmp/udhcpc");
1088
1089	unlink("/tmp/ppp/ip-up");
1090	unlink("/tmp/ppp/ip-down");
1091	unlink("/tmp/ppp/options");
1092	rmdir("/tmp/ppp");
1093
1094#ifdef ASUS_EXT
1095	if(nvram_invmatch("wan_ifname_t", "")) wan_down(nvram_safe_get("wan_ifname_t"));
1096#endif
1097
1098	dprintf("done\n");
1099}
1100
1101static int
1102add_ns(char *wan_ifname)
1103{
1104	FILE *fp;
1105	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1106	char word[100], *next;
1107	char line[100];
1108
1109	/* Figure out nvram variable name prefix for this i/f */
1110	if (wan_prefix(wan_ifname, prefix) < 0)
1111		return -1;
1112
1113	/* Open resolv.conf to read */
1114	if (!(fp = fopen("/tmp/resolv.conf", "r+"))) {
1115		perror("/tmp/resolv.conf");
1116		return errno;
1117	}
1118
1119	/* Append only those not in the original list */
1120	foreach(word, nvram_safe_get(strcat_r(prefix, "dns", tmp)), next)
1121	{
1122		fseek(fp, 0, SEEK_SET);
1123		while (fgets(line, sizeof(line), fp)) {
1124			char *token = strtok(line, " \t\n");
1125
1126			if (!token || strcmp(token, "nameserver") != 0)
1127				continue;
1128			if (!(token = strtok(NULL, " \t\n")))
1129				continue;
1130
1131			if (!strcmp(token, word))
1132				break;
1133		}
1134		if (feof(fp))
1135			fprintf(fp, "nameserver %s\n", word);
1136	}
1137	fclose(fp);
1138
1139#ifdef ASUS_EXT
1140	stop_dns();
1141	start_dns();
1142#else
1143	/* notify dnsmasq */
1144	snprintf(tmp, sizeof(tmp), "-%d", SIGHUP);
1145	eval("killall", tmp, "dnsmasq");
1146#endif
1147
1148	return 0;
1149}
1150
1151static int
1152del_ns(char *wan_ifname)
1153{
1154	FILE *fp, *fp2;
1155	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1156	char word[100], *next;
1157	char line[100];
1158
1159	/* Figure out nvram variable name prefix for this i/f */
1160	if (wan_prefix(wan_ifname, prefix) < 0)
1161		return -1;
1162
1163	/* Open resolv.conf to read */
1164	if (!(fp = fopen("/tmp/resolv.conf", "r"))) {
1165		perror("fopen /tmp/resolv.conf");
1166		return errno;
1167	}
1168	/* Open resolv.tmp to save updated name server list */
1169	if (!(fp2 = fopen("/tmp/resolv.tmp", "w"))) {
1170		perror("fopen /tmp/resolv.tmp");
1171		fclose(fp);
1172		return errno;
1173	}
1174	/* Copy updated name servers */
1175	while (fgets(line, sizeof(line), fp)) {
1176		char *token = strtok(line, " \t\n");
1177
1178		if (!token || strcmp(token, "nameserver") != 0)
1179			continue;
1180		if (!(token = strtok(NULL, " \t\n")))
1181			continue;
1182
1183		foreach(word, nvram_safe_get(strcat_r(prefix, "dns", tmp)), next)
1184			if (!strcmp(word, token))
1185				break;
1186		if (!next)
1187			fprintf(fp2, "nameserver %s\n", token);
1188	}
1189	fclose(fp);
1190	fclose(fp2);
1191	/* Use updated file as resolv.conf */
1192	unlink("/tmp/resolv.conf");
1193	rename("/tmp/resolv.tmp", "/tmp/resolv.conf");
1194
1195#ifdef ASUS_EXT
1196	stop_dns();
1197	start_dns();
1198#else
1199	/* notify dnsmasq */
1200	snprintf(tmp, sizeof(tmp), "-%d", SIGHUP);
1201	eval("killall", tmp, "dnsmasq");
1202#endif
1203
1204	return 0;
1205}
1206
1207void
1208wan_up(char *wan_ifname)
1209{
1210	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1211	char *wan_proto;
1212
1213	/* Figure out nvram variable name prefix for this i/f */
1214	if (wan_prefix(wan_ifname, prefix) < 0)
1215		return;
1216
1217	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
1218
1219	dprintf("%s %s\n", wan_ifname, wan_proto);
1220
1221	/* Set default route to gateway if specified */
1222	if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1223		route_add(wan_ifname, 0, "0.0.0.0",
1224			nvram_safe_get(strcat_r(prefix, "gateway", tmp)),
1225			"0.0.0.0");
1226
1227	/* Install interface dependent static routes */
1228	add_wan_routes(wan_ifname);
1229
1230	/* Add dns servers to resolv.conf */
1231	add_ns(wan_ifname);
1232
1233	/* Sync time */
1234	//start_ntpc();
1235
1236#ifdef ASUS_EXT
1237	update_wan_status(1);
1238
1239#ifdef NOIPTABLES
1240	start_firewall2(wan_ifname);
1241#else
1242	start_firewall_ex(wan_ifname, nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)), "br0", nvram_safe_get("lan_ipaddr"));
1243#endif
1244	start_ddns();
1245	stop_upnp();
1246	start_upnp();
1247	if (strcmp(wan_proto, "bigpond")==0)
1248	{
1249		stop_bpalogin();
1250		start_bpalogin();
1251	}
1252
1253#endif
1254
1255
1256#ifdef QOS
1257	// start qos related
1258	start_qos(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)));
1259#endif
1260
1261	dprintf("done\n");
1262}
1263
1264void
1265wan_down(char *wan_ifname)
1266{
1267	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1268	char *wan_proto;
1269
1270	/* Figure out nvram variable name prefix for this i/f */
1271	if (wan_prefix(wan_ifname, prefix) < 0)
1272		return;
1273
1274	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
1275
1276	dprintf("%s %s\n", wan_ifname, wan_proto);
1277
1278	/* Remove default route to gateway if specified */
1279	if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1280		route_del(wan_ifname, 0, "0.0.0.0",
1281			nvram_safe_get(strcat_r(prefix, "gateway", tmp)),
1282			"0.0.0.0");
1283
1284	/* Remove interface dependent static routes */
1285	del_wan_routes(wan_ifname);
1286
1287	/* Update resolv.conf */
1288	del_ns(wan_ifname);
1289
1290#ifdef ASUS_EXT
1291	printf("update wan status\n");
1292	update_wan_status(0);
1293#ifdef CDMA
1294	if ((strcmp(wan_proto, "bigpond")==0) || (strcmp(wan_proto, "cdma") == 0)) {
1295#else
1296	if (strcmp(wan_proto, "bigpond")==0){
1297
1298#endif
1299	 	stop_bpalogin();
1300	}
1301#endif
1302
1303	dprintf("done\n");
1304}
1305
1306#ifdef ASUS_EXT
1307#ifndef FLASH2M
1308void
1309lan_up(char *lan_ifname)
1310{
1311	FILE *fp;
1312	char word[100], *next;
1313	char line[100];
1314
1315	/* Set default route to gateway if specified */
1316	route_add(lan_ifname, 0, "0.0.0.0",
1317			nvram_safe_get("lan_gateway"),
1318			"0.0.0.0");
1319
1320	/* Open resolv.conf to read */
1321	if (!(fp = fopen("/tmp/resolv.conf", "w"))) {
1322		perror("/tmp/resolv.conf");
1323		return errno;
1324	}
1325
1326	if (nvram_invmatch("lan_gateway", ""))
1327		fprintf(fp, "nameserver %s\n", nvram_safe_get("lan_gateway"));
1328
1329	foreach(word, nvram_safe_get("lan_dns"), next)
1330	{
1331		fprintf(fp, "nameserver %s\n", word);
1332	}
1333	fclose(fp);
1334
1335	/* Sync time */
1336	//start_ntpc();
1337}
1338
1339void
1340lan_down(char *lan_ifname)
1341{
1342	/* Remove default route to gateway if specified */
1343	route_del(lan_ifname, 0, "0.0.0.0",
1344			nvram_safe_get("lan_gateway"),
1345			"0.0.0.0");
1346
1347	/* remove resolv.conf */
1348	unlink("/tmp/resolv.conf");
1349}
1350
1351
1352void
1353lan_up_ex(char *lan_ifname)
1354{
1355	FILE *fp;
1356	char word[100], *next;
1357	char line[100];
1358
1359	/* Set default route to gateway if specified */
1360	route_add(lan_ifname, 0, "0.0.0.0",
1361			nvram_safe_get("lan_gateway_t"),
1362			"0.0.0.0");
1363
1364	/* Open resolv.conf to read */
1365	if (!(fp = fopen("/tmp/resolv.conf", "w"))) {
1366		perror("/tmp/resolv.conf");
1367		return errno;
1368	}
1369
1370	if (nvram_invmatch("lan_gateway_t", ""))
1371		fprintf(fp, "nameserver %s\n", nvram_safe_get("lan_gateway_t"));
1372
1373	foreach(word, nvram_safe_get("lan_dns_t"), next)
1374	{
1375		fprintf(fp, "nameserver %s\n", word);
1376	}
1377	fclose(fp);
1378
1379	/* Sync time */
1380	//start_ntpc();
1381	//update_lan_status(1);
1382}
1383
1384void
1385lan_down_ex(char *lan_ifname)
1386{
1387	/* Remove default route to gateway if specified */
1388	route_del(lan_ifname, 0, "0.0.0.0",
1389			nvram_safe_get("lan_gateway_t"),
1390			"0.0.0.0");
1391
1392	/* remove resolv.conf */
1393	unlink("/tmp/resolv.conf");
1394
1395	update_lan_status(0);
1396}
1397#endif
1398#endif
1399
1400static int
1401notify_nas(char *type, char *ifname, char *action)
1402{
1403	char *argv[] = {"nas4not", type, ifname, action,
1404			NULL,	/* role */
1405			NULL,	/* crypto */
1406			NULL,	/* auth */
1407			NULL,	/* passphrase */
1408			NULL,	/* ssid */
1409			NULL};
1410	char *str = NULL;
1411	int retries = 10;
1412	char tmp[100], prefix[] = "wlXXXXXXXXXX_";
1413	int unit;
1414	char remote[ETHER_ADDR_LEN];
1415	char ssid[48], pass[80], auth[16], crypto[16], role[8];
1416	int i;
1417
1418	/* the wireless interface must be configured to run NAS */
1419	wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
1420	snprintf(prefix, sizeof(prefix), "wl%d_", unit);
1421	if (nvram_match(strcat_r(prefix, "akm", tmp), "") &&
1422	    nvram_match(strcat_r(prefix, "auth_mode", tmp), "none"))
1423		return 0;
1424
1425	/* find WDS link configuration */
1426	wl_ioctl(ifname, WLC_WDS_GET_REMOTE_HWADDR, remote, ETHER_ADDR_LEN);
1427	for (i = 0; i < MAX_NVPARSE; i ++) {
1428		char mac[ETHER_ADDR_STR_LEN];
1429		uint8 ea[ETHER_ADDR_LEN];
1430
1431		if (get_wds_wsec(unit, i, mac, role, crypto, auth, ssid, pass) &&
1432		    ether_atoe(mac, ea) && !bcmp(ea, remote, ETHER_ADDR_LEN)) {
1433			argv[4] = role;
1434			argv[5] = crypto;
1435			argv[6] = auth;
1436			argv[7] = pass;
1437			argv[8] = ssid;
1438			break;
1439		}
1440	}
1441
1442	/* did not find WDS link configuration, use wireless' */
1443	if (i == MAX_NVPARSE) {
1444		/* role */
1445		argv[4] = "auto";
1446		/* crypto */
1447		argv[5] = nvram_safe_get(strcat_r(prefix, "crypto", tmp));
1448		/* auth mode */
1449		argv[6] = nvram_safe_get(strcat_r(prefix, "akm", tmp));
1450		/* passphrase */
1451		argv[7] = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
1452		/* ssid */
1453		argv[8] = nvram_safe_get(strcat_r(prefix, "ssid", tmp));
1454	}
1455
1456	/* wait till nas is started */
1457	while (retries -- > 0 && !(str = file2str("/tmp/nas.lan.pid")))
1458		sleep(1);
1459	if (str) {
1460		int pid;
1461		free(str);
1462		return _eval(argv, ">/dev/console", 0, &pid);
1463	}
1464	return -1;
1465}
1466
1467int
1468hotplug_net(void)
1469{
1470	char *lan_ifname = nvram_safe_get("lan_ifname");
1471	char *interface, *action;
1472
1473	if (!(interface = getenv("INTERFACE")) ||
1474	    !(action = getenv("ACTION")))
1475		return EINVAL;
1476
1477	if (strncmp(interface, "wds", 3))
1478		return 0;
1479
1480	if (!strcmp(action, "register")) {
1481		/* Bring up the interface and add to the bridge */
1482		ifconfig(interface, IFUP, NULL, NULL);
1483
1484		/* Bridge WDS interfaces */
1485		if (!strncmp(lan_ifname, "br", 2) &&
1486		    eval("brctl", "addif", lan_ifname, interface))
1487		    return 0;
1488
1489		/* Notify NAS of adding the interface */
1490		notify_nas("lan", interface, "up");
1491	}
1492	return 0;
1493}
1494
1495
1496int
1497wan_ifunit(char *wan_ifname)
1498{
1499	int unit;
1500	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1501
1502	if ((unit = ppp_ifunit(wan_ifname)) >= 0)
1503		return unit;
1504	else {
1505		for (unit = 0; unit < MAX_NVPARSE; unit ++) {
1506			snprintf(prefix, sizeof(prefix), "wan%d_", unit);
1507			if (nvram_match(strcat_r(prefix, "ifname", tmp), wan_ifname) &&
1508			    (nvram_match(strcat_r(prefix, "proto", tmp), "dhcp") ||
1509			     nvram_match(strcat_r(prefix, "proto", tmp), "bigpond") ||
1510#ifdef CDMA
1511			     nvram_match(strcat_r(prefix, "proto", tmp), "cdma") ||
1512#endif
1513			     nvram_match(strcat_r(prefix, "proto", tmp), "static")))
1514				return unit;
1515		}
1516	}
1517	return -1;
1518}
1519
1520int
1521preset_wan_routes(char *wan_ifname)
1522{
1523	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1524
1525
1526	/* Figure out nvram variable name prefix for this i/f */
1527	if (wan_prefix(wan_ifname, prefix) < 0)
1528		return -1;
1529
1530	/* Set default route to gateway if specified */
1531	if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1532	{
1533		route_add(wan_ifname, 0, "0.0.0.0", "0.0.0.0", "0.0.0.0");
1534	}
1535
1536	/* Install interface dependent static routes */
1537	add_wan_routes(wan_ifname);
1538	return 0;
1539}
1540
1541int
1542wan_primary_ifunit(void)
1543{
1544	int unit;
1545
1546	for (unit = 0; unit < MAX_NVPARSE; unit ++) {
1547		char tmp[100], prefix[] = "wanXXXXXXXXXX_";
1548		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
1549		if (nvram_match(strcat_r(prefix, "primary", tmp), "1"))
1550			return unit;
1551	}
1552
1553	return 0;
1554}
1555
1556