1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License as
4 * published by the Free Software Foundation; either version 2 of
5 * the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
15 * MA 02111-1307 USA
16 *
17 * Copyright 2014, ASUSTeK Inc.
18 * All Rights Reserved.
19 *
20 * THIS SOFTWARE IS OFFERED "AS IS", AND ASUS GRANTS NO WARRANTIES OF ANY
21 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
22 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
23 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
24 *
25 */
26
27#include <sys/socket.h>
28#include <sys/ioctl.h>
29#include <stdio.h>
30#include <netinet/in.h>
31#include <string.h>
32#include <errno.h>
33#include <signal.h>
34#include <sys/time.h>
35#include <bcmnvram.h>
36#include <stdlib.h>
37#include <rc.h>
38#include <sys/ipc.h>
39#include <sys/shm.h>
40#include <sys/sysinfo.h>
41#include <wlutils.h>
42#include "../networkmap/networkmap.h"
43#include <fcntl.h>
44#include <resolv.h>
45#include <netdb.h>
46#include <netinet/in.h>
47#include <netinet/ip_icmp.h>
48
49#if defined(RTCONFIG_RALINK)
50#elif defined(RTCONFIG_QCA)
51#else
52#include <wlioctl.h>
53#endif
54
55#define POLL_INTERVAL_SEC 30
56#define POLL_SHORT_INTERVAL_SEC 10
57#define MAC_STR_LEN 18
58#define IP_STR_LEN 15
59#define WIFI_INF_MAX 3
60#define MAX_STA_COUNT   128
61#define DHCP_LEASE "var/lib/misc/dnsmasq.leases"
62#define PACKETSIZE  64
63
64#define KGINFO(fmt, arg...) \
65        do { \
66                _dprintf("KeyGuard %lu: "fmt, uptime(), ##arg); \
67        }while (0)
68
69#define KGDBG(fmt, arg...) \
70	do { \
71		if(kg_dbg) \
72		_dprintf("KeyGuard %lu: "fmt, uptime(), ##arg); \
73	}while (0)
74
75static struct itimerval itv;
76int KG_WAN = 0;
77int KG_STREAM = 0;
78int KG_WIFI_RADIO = 0;
79int KG_RADIO_2G = 0;
80int KG_RADIO_5G = 0;
81char router_orig_wan_enable[WAN_UNIT_MAX][32];
82char router_orig_txchain[WIFI_INF_MAX][32];
83char router_orig_rxchain[WIFI_INF_MAX][32];
84char router_orig_wl_radio[WIFI_INF_MAX][32];
85int kdevice_status;
86int count = 0;
87int kg_dbg = 0;
88
89typedef struct sta_info {
90	char mac[MAC_STR_LEN];
91	char ip[IP_STR_LEN];
92	int enable;
93	struct sta_info *next;
94}kdevice_t;
95
96kdevice_t *KeyDevice = NULL;
97
98struct packet
99{
100    struct icmphdr hdr;
101    char msg[PACKETSIZE-sizeof(struct icmphdr)];
102};
103
104int pid=-1;
105struct protoent *proto=NULL;
106int cnt=1;
107
108/*--------------------------------------------------------------------*/
109/*--- checksum - standard 1s complement checksum                   ---*/
110/*--------------------------------------------------------------------*/
111unsigned short checksum(void *b, int len)
112{
113	unsigned short *buf = b;
114	unsigned int sum=0;
115	unsigned short result;
116
117	for ( sum = 0; len > 1; len -= 2 )
118		sum += *buf++;
119	if ( len == 1 )
120		sum += *(unsigned char*)buf;
121	sum = (sum >> 16) + (sum & 0xFFFF);
122	sum += (sum >> 16);
123	result = ~sum;
124
125	return result;
126}
127
128
129/*--------------------------------------------------------------------*/
130/*--- ping - Create message and send it.                           ---*/
131/*--------------------------------------------------------------------*/
132int ping(char *address)
133{
134	const int val=255;
135	int i, sd;
136	struct packet pckt;
137	struct sockaddr_in r_addr;
138	int retry;
139	struct hostent *hname;
140	struct sockaddr_in addr_ping,*addr;
141	int len;
142	char r_ip[INET_ADDRSTRLEN];
143
144	pid = getpid();
145	proto = getprotobyname("ICMP");
146	hname = gethostbyname(address);
147	bzero(&addr_ping, sizeof(addr_ping));
148	addr_ping.sin_family = hname->h_addrtype;
149	addr_ping.sin_port = 0;
150	addr_ping.sin_addr.s_addr = *(long*)hname->h_addr;
151
152	addr = &addr_ping;
153
154	sd = socket(PF_INET, SOCK_RAW, proto->p_proto);
155	if ( sd < 0 )
156	{
157		perror("socket");
158		return 1;
159	}
160
161	if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
162    	{
163        	perror("Set TTL option");
164        	return 1;
165	}
166	if ( fcntl(sd, F_SETFL, O_NONBLOCK) != 0 )
167    	{
168		perror("Request nonblocking I/O");
169		return 1;
170	}
171
172	for (retry=0; retry < 3; retry++)
173	{
174		len=sizeof(r_addr);
175
176		if ( recvfrom(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&r_addr, &len) > 0 )
177		{
178			inet_ntop(r_addr.sin_family, &(r_addr.sin_addr), r_ip, sizeof(r_ip));
179			if(strcmp(address, r_ip) == 0) {
180				close(sd);
181				return 0;
182			}
183		}
184
185		bzero(&pckt, sizeof(pckt));
186		pckt.hdr.type = ICMP_ECHO;
187		pckt.hdr.un.echo.id = pid;
188
189		for ( i = 0; i < sizeof(pckt.msg)-1; i++ )
190			pckt.msg[i] = i+'0';
191
192		pckt.msg[i] = 0;
193		pckt.hdr.un.echo.sequence = cnt++;
194		pckt.hdr.checksum = checksum(&pckt, sizeof(pckt));
195
196		if ( sendto(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 )
197			perror("sendto");
198
199		usleep(300000);
200		KGDBG("Ping %s ...(%d)\n", address, retry);
201
202	}
203
204	close(sd);
205	return 1;
206}
207
208
209
210static void alarmtimer(unsigned long sec, unsigned long usec)
211{
212	itv.it_value.tv_sec  = sec;
213	itv.it_value.tv_usec = usec;
214	itv.it_interval = itv.it_value;
215	setitimer(ITIMER_REAL, &itv, NULL);
216}
217
218int check_auth_device_wifi() {
219
220	char ifname[32], vifname[32];
221	char prefix[32];
222	char tmp[128];
223	char ea[ETHER_ADDR_LEN];
224	char *next;
225	int ret, unit;
226	int vidx;
227	int mcnt;
228	struct maclist *mac_list;
229	int mac_list_size;
230	kdevice_t *ptr;
231	int kdevice_found;
232
233#if defined(RTCONFIG_RALINK)
234#elif defined(RTCONFIG_QCA)
235#elif defined(RTCONFIG_QTN)
236#else /* BCM */
237	kdevice_found = 0;
238	mac_list_size = sizeof(mac_list->count) + MAX_STA_COUNT * sizeof(struct ether_addr);
239	mac_list = malloc(mac_list_size);
240        if(!mac_list)
241                goto exit;
242
243	foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
244		memset(mac_list, 0, mac_list_size);
245		strcpy((char*)mac_list, "authe_sta_list");
246		if(wl_ioctl(ifname, WLC_GET_VAR, mac_list, mac_list_size))
247			continue;
248		for(mcnt=0; mcnt < mac_list->count; mcnt++) {
249			ether_etoa((void *)&mac_list->ea[mcnt], ea);
250			ptr = KeyDevice;
251			while(ptr != NULL) {
252				if(strcmp(ea, ptr->mac) == 0 && ptr->enable) {
253					KGDBG("detect key device [wifi authe - %s]: %s (%s)\n", ifname, ptr->mac, ptr->ip);
254                                        kdevice_found = 1;
255                                        break;
256                                }
257                                ptr = ptr->next;
258                        }
259			if(kdevice_found) goto exit;
260		}
261
262		//sub-unit
263		for(vidx = 1; vidx < 4; vidx++) {
264			snprintf(prefix, sizeof(prefix), "wl%d.%d_", unit, vidx);
265			if (nvram_match(strcat_r(prefix, "bss_enabled", tmp), "1"))
266			{
267				sprintf(vifname, "wl%d.%d", unit, vidx);
268				memset(mac_list, 0, mac_list_size);
269				strcpy((char*) mac_list, "authe_sta_list");
270				if (wl_ioctl(vifname, WLC_GET_VAR, mac_list, mac_list_size))
271					continue;
272				for(mcnt=0; mcnt < mac_list->count; mcnt++) {
273                                        ether_etoa((void *)&mac_list->ea[mcnt], ea);
274					ptr = KeyDevice;
275                                	while(ptr != NULL) {
276                                        	if(strcmp(ea, ptr->mac) == 0 && ptr->enable) {
277                                                	KGDBG("detect key device [wifi authe - %s]: %s (%s)\n", ifname, ptr->mac, ptr->ip);
278                                                	kdevice_found = 1;
279                                                	break;
280                                        	}
281                                        	ptr = ptr->next;
282                                	}
283                                	if(kdevice_found) goto exit;
284				}
285			}
286
287		}
288        }
289
290exit:
291	if(mac_list) free(mac_list);
292#endif
293	return kdevice_found;
294}
295
296int detect_by_echo_reply() {
297
298	int kdevice_found = 0;
299	kdevice_t *ptr;
300	char cmd[128];
301
302	ptr = KeyDevice;
303	while(ptr != NULL) {
304
305		if(strcmp(ptr->ip, "0.0.0.0") == 0) {
306			kg_update_ip_from_dhcp_lease(ptr);
307			if(strcmp(ptr->ip, "0.0.0.0") == 0) //static ip? lookup network map.
308				kg_update_ip_from_nmap();
309		}
310
311		if(strcmp(ptr->ip, "0.0.0.0") != 0 && ptr->enable) {
312			if(!ping(ptr->ip)) {
313				kdevice_found = 1;
314				KGDBG("detect key device [echo reply]: %s (%s)\n", ptr->mac, ptr->ip);
315                		break;
316        		}
317		}
318
319		ptr = ptr->next;
320	}
321
322	return kdevice_found;
323}
324
325
326static void kg_watchdog(int sig) {
327
328	int i, shm_client_info_id;
329        void *shared_client_info=(void *) 0;
330        char mac_buf[32];
331        P_CLIENT_DETAIL_INFO_TABLE p_client_info_tab;
332        int lock;
333	int timeout;
334	int kdevice;
335	kdevice_t *ptr;
336
337	if ( !nvram_get_int("wlready") ||
338	     nvram_get_int("sw_mode") != SW_MODE_ROUTER ||
339	     (!KG_WAN && !KG_STREAM && !KG_WIFI_RADIO) ||
340	     KeyDevice == NULL)
341		return;
342
343	/* detect key device state:
344		1. wireless authe list
345		2. icmp echo
346		3. arp
347	*/
348
349	// Check wireless sta first
350	kdevice = check_auth_device_wifi();
351
352	// Check by ping
353	if(!kdevice) {
354		alarmtimer(0, 0);
355		kdevice = detect_by_echo_reply();
356		alarmtimer(POLL_INTERVAL_SEC, 0);
357	}
358
359	if(!kdevice && kdevice_status) {	// All key devices were left? send arp to confirm.
360
361		if(count == 0) {
362			timeout = 20;
363			alarmtimer(0, 0);
364			KGDBG("Send arp...\n");
365			killall("networkmap", SIGUSR1);
366			while(1)
367			{
368				sleep(1);
369				timeout--;
370				if(!nvram_get_int("networkmap_fullscan") || !timeout) {
371					break;
372				}
373			};
374			sleep(10);
375			kg_update_ip_from_nmap();
376			alarmtimer(POLL_SHORT_INTERVAL_SEC, 0);
377		}
378
379		lock = file_lock("networkmap");
380		shm_client_info_id = shmget((key_t)1001, sizeof(CLIENT_DETAIL_INFO_TABLE), 0666|IPC_CREAT);
381		if (shm_client_info_id == -1){
382			fprintf(stderr,"shmget failed\n");
383			file_unlock(lock);
384			return;
385		}
386
387		shared_client_info = shmat(shm_client_info_id,(void *) 0,0);
388		if (shared_client_info == (void *)-1){
389			fprintf(stderr,"shmat failed\n");
390			file_unlock(lock);
391			return;
392		}
393
394		kdevice = 0;
395		p_client_info_tab = (P_CLIENT_DETAIL_INFO_TABLE)shared_client_info;
396		for(i=0; i<p_client_info_tab->ip_mac_num; i++) {
397			memset(mac_buf, 0, 32);
398
399			if(p_client_info_tab->exist[i]==1) {
400				sprintf(mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X",
401				p_client_info_tab->mac_addr[i][0],p_client_info_tab->mac_addr[i][1],
402				p_client_info_tab->mac_addr[i][2],p_client_info_tab->mac_addr[i][3],
403				p_client_info_tab->mac_addr[i][4],p_client_info_tab->mac_addr[i][5]
404				);
405
406				ptr = KeyDevice;
407				while(ptr != NULL) {
408					if(strcmp(mac_buf, ptr->mac) == 0 && ptr->enable) {
409						KGDBG("detect key device [arp]: %s (%s)\n", ptr->mac, ptr->ip);
410						kdevice = 1;
411						break;
412					}
413					ptr = ptr->next;
414				}
415			}
416			if(kdevice)	break;
417        	}
418
419
420		ptr = NULL;
421        	shmdt(shared_client_info);
422        	file_unlock(lock);
423	}
424
425
426	if(kdevice_status != kdevice) {
427		if(kdevice)
428			alarmtimer(POLL_SHORT_INTERVAL_SEC, 0);
429		if(count > 0) {
430			count = 0;
431			kg_trigger(kdevice);
432		}
433		else
434			count++;
435	}
436
437        return 0;
438}
439
440void kg_exit(int signo) {
441
442	kdevice_t *next;
443	alarmtimer(0, 0);
444	signal(SIGTERM, SIG_IGN);
445	kg_restore_original();
446	KGINFO("Exit...\n");
447	while(KeyDevice) {
448		next = KeyDevice->next;
449		free(KeyDevice);
450		KeyDevice = next;
451	}
452	remove("/var/run/keyguard.pid");
453	exit(0);
454}
455
456
457/*--------------------------------------------------------------------*/
458/*--- Condition changed, update rule and key device                ---*/
459/*--------------------------------------------------------------------*/
460void kg_update_condition(int signo) {
461
462	KGDBG("updade rule and key devices list\n");
463	alarmtimer(0,0);
464	kg_init_setting();
465	alarmtimer(POLL_INTERVAL_SEC, 0);
466}
467
468/*--------------------------------------------------------------------*/
469/*--- Retrieve key device ip from dhcp lease                       ---*/
470/*--------------------------------------------------------------------*/
471void kg_update_ip_from_dhcp_lease(kdevice_t *ptr) {
472
473	FILE *fp;
474	char buf[256];
475	char word[256], *next_word;
476	char mac[MAC_STR_LEN];
477        char ip[IP_STR_LEN];
478	int item;
479
480	fp = fopen(DHCP_LEASE, "r");
481	if(fp==NULL)
482		return;
483	while(fgets(buf, sizeof(buf), fp) != NULL) {
484		item = 0;
485		foreach(word, buf, next_word) {
486			if(item == 1)	// mac
487				strncpy(mac, word, MAC_STR_LEN);
488			if(item == 2) {	// ip
489				strncpy(ip, word, IP_STR_LEN);
490				break;
491			}
492			item++;
493		}
494		if(!strcasecmp(ptr->mac, mac)) {
495			strcpy(ptr->ip, ip);
496			break;
497		}
498	}
499
500	fclose(fp);
501}
502
503/*--------------------------------------------------------------------*/
504/*--- Retrieve key device ip by arp                                ---*/
505/*--------------------------------------------------------------------*/
506void kg_update_ip_from_nmap() {
507
508	int i, shm_client_info_id;
509	void *shared_client_info=(void *) 0;
510	P_CLIENT_DETAIL_INFO_TABLE p_client_info_tab;
511	int lock;
512	char mac[MAC_STR_LEN];
513	char ip[IP_STR_LEN];
514	kdevice_t *ptr;
515
516	lock = file_lock("networkmap");
517	shm_client_info_id = shmget((key_t)1001, sizeof(CLIENT_DETAIL_INFO_TABLE), 0666|IPC_CREAT);
518	if (shm_client_info_id == -1){
519		fprintf(stderr,"shmget failed\n");
520		file_unlock(lock);
521		return 0;
522	}
523
524	shared_client_info = shmat(shm_client_info_id,(void *) 0,0);
525	if (shared_client_info == (void *)-1){
526		fprintf(stderr,"shmat failed\n");
527		file_unlock(lock);
528		return 0;
529	}
530
531	p_client_info_tab = (P_CLIENT_DETAIL_INFO_TABLE)shared_client_info;
532	for(i=0; i<p_client_info_tab->ip_mac_num; i++) {
533		sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",
534                                p_client_info_tab->mac_addr[i][0],p_client_info_tab->mac_addr[i][1],
535                                p_client_info_tab->mac_addr[i][2],p_client_info_tab->mac_addr[i][3],
536                                p_client_info_tab->mac_addr[i][4],p_client_info_tab->mac_addr[i][5]
537                                );
538		sprintf(ip, "%d.%d.%d.%d",
539                                p_client_info_tab->ip_addr[i][0],p_client_info_tab->ip_addr[i][1],
540                		p_client_info_tab->ip_addr[i][2],p_client_info_tab->ip_addr[i][3]);
541
542		ptr = KeyDevice;
543		while(ptr != NULL) {
544			if(strcmp(mac, ptr->mac) == 0) {
545				if(strcmp(ip, ptr->ip) != 0)
546					strncpy(ptr->ip, ip, IP_STR_LEN);
547				break;
548			}
549			ptr = ptr->next;
550		}
551        }
552        shmdt(shared_client_info);
553        file_unlock(lock);
554}
555
556/*--------------------------------------------------------------------*/
557/*--- init keyguard                                                ---*/
558/*--------------------------------------------------------------------*/
559void kg_init_setting() {
560
561	kdevice_t *sta, *ptr;
562	char enable[512], *next_enable;
563	char word[4096], *next_word;
564	int time;
565
566	// Rule
567	KG_WAN = nvram_get_int("kg_wan_enable");
568	KG_STREAM = nvram_get_int("kg_powersaving_enable");
569	KG_WIFI_RADIO = nvram_get_int("kg_wl_radio_enable");
570	if(KG_WIFI_RADIO) {
571		if(nvram_get_int("kg_wl_radio")) {
572			KG_RADIO_2G = 0;
573			KG_RADIO_5G = 1;
574		}
575		else {
576			KG_RADIO_2G = 1;
577			KG_RADIO_5G = 0;
578		}
579	}
580	else {
581		KG_RADIO_2G = KG_RADIO_5G = 0;
582	}
583
584	// Key Devices
585	while(KeyDevice != NULL) {
586		ptr = KeyDevice->next;
587		free(KeyDevice);
588		KeyDevice = ptr;
589	}
590
591	foreach_62(word, nvram_safe_get("kg_mac"), next_word) {
592
593		sta = malloc(sizeof(kdevice_t));
594		memset(sta, 0, sizeof(kdevice_t));
595		strncpy(sta->mac, word, MAC_STR_LEN);
596		strcpy(sta->ip, "0.0.0.0");
597		sta->enable = 0;
598		sta->next = NULL;
599
600		if(KeyDevice == NULL) {
601			KeyDevice = sta;
602			ptr = KeyDevice;
603		}
604		else {
605			ptr->next = sta;
606			ptr = ptr->next;
607		}
608	}
609
610	ptr = KeyDevice;
611	foreach_62(enable, nvram_safe_get("kg_device_enable"), next_enable) {
612		if(ptr == NULL) break;
613		if(strlen(enable) > 0)
614			ptr->enable = atoi(enable);
615		ptr = ptr->next;
616	}
617
618	time = 20;
619	killall("networkmap", SIGUSR1);
620	while(1)
621	{
622		sleep(1);
623		time--;
624		if(!nvram_get_int("networkmap_fullscan") || !time)
625		break;
626	};
627	sleep(10);
628
629	kg_update_ip_from_nmap();
630
631	kdevice_status = 1;
632
633	ptr = KeyDevice;
634	while(ptr != NULL) {
635		if(strcmp(ptr->ip, "0.0.0.0") == 0)
636			kg_update_ip_from_dhcp_lease(ptr);
637		KGDBG("key device: %s (%s) [%d]\n", ptr->mac, ptr->ip, ptr->enable);
638		ptr = ptr->next;
639	};
640
641}
642
643/*--------------------------------------------------------------------*/
644/*--- keyguard condition trigger                                   ---*/
645/*--------------------------------------------------------------------*/
646void kg_trigger(int kdevice) {
647
648	char ifname[32];
649        char tmp[32];
650        char *next;
651        int unit;
652
653	KGDBG("*** %s ***\n", kdevice ? "key device is back" : "all key devices were left");
654
655	if(!kdevice) {	// apply the setting for all key devices leave
656
657		if(KG_WAN) {
658			KGINFO("--- WAN DISABLE ---\n");
659			for(unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; ++unit)
660                		stop_wan_if(unit);
661		}
662
663		if(KG_STREAM) {
664			KGINFO("--- ENTER WIFI POWER SAVING MODE ---\n");
665			foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
666#if defined(RTCONFIG_RALINK)
667#elif defined(RTCONFIG_QCA)
668#else /* BCM */
669
670#if defined(RTCONFIG_QTN)
671#else
672				eval("wl", "-i", ifname, "txchain", "1");
673				eval("wl", "-i", ifname, "rxchain", "1");
674				eval("wl", "-i", ifname, "down");
675				eval("wl", "-i", ifname, "up");
676#endif
677#endif
678	           	}
679        	}
680
681		if(KG_WIFI_RADIO) {
682			KGINFO("--- DISABLE WIFI - %s ---\n", KG_RADIO_2G ? "2GHz" : "5GHz");
683			unit = 0;
684                        foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
685                                sprintf(tmp, "wl%d_nband", unit);
686				if((nvram_get_int(tmp) == 2 && KG_RADIO_2G) ||
687				   (nvram_get_int(tmp) == 1 && KG_RADIO_5G)) {
688#if defined(RTCONFIG_RALINK)
689#elif defined(RTCONFIG_QCA)
690#else /* BCM */
691
692#if defined(RTCONFIG_QTN)
693#else
694					eval("wl", "-i", ifname, "radio", "off");
695#endif
696#endif
697				}
698				else {
699#if defined(RTCONFIG_RALINK)
700#elif defined(RTCONFIG_QCA)
701#else /* BCM */
702
703#if defined(RTCONFIG_QTN)
704#else
705					eval("wl", "-i", ifname, "radio", "on");
706#endif
707#endif
708				}
709                                unit++;
710                        }
711		}
712	}
713	else {	// key device is back. Roll back to normal setting
714		if(KG_WAN) {
715			KGINFO("--- WAN ENABLE ---\n");
716			for(unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; ++unit)
717                		start_wan_if(unit);
718		}
719
720		if(KG_STREAM) {
721			KGINFO("--- LEAVE WIFI POWER SAVING MODE ---\n");
722			unit = 0;
723			foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
724#if defined(RTCONFIG_RALINK)
725#elif defined(RTCONFIG_QCA)
726#else /* BCM */
727
728#if defined(RTCONG_QTN)
729#else
730				eval("wl", "-i", ifname, "txchain", router_orig_txchain[unit]);
731				eval("wl", "-i", ifname, "rxchain", router_orig_rxchain[unit]);
732				eval("wl", "-i", ifname, "down");
733				eval("wl", "-i", ifname, "up");
734#endif
735#endif
736				unit++;
737			}
738		}
739
740		if(KG_WIFI_RADIO) {
741			KGINFO("--- ENABLE WIFI - %s ---\n", KG_RADIO_2G ? "2GHz" : "5GHz");
742			unit = 0;
743			foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
744				sprintf(tmp, "wl%d_nband", unit);
745				if((nvram_get_int(tmp) == 2 && KG_RADIO_2G) ||
746                                   (nvram_get_int(tmp) == 1 && KG_RADIO_5G)) {
747#if defined(RTCONFIG_RALINK)
748#elif defined(RTCONFIG_QCA)
749#else /* BCM */
750
751#if defined(RTCONG_QTN)
752#else
753					eval("wl", "-i", ifname, "radio", "on");
754#endif
755#endif
756				}
757				unit++;
758			}
759		}
760	}
761
762
763	kdevice_status = kdevice;
764
765}
766
767/*--------------------------------------------------------------------*/
768/*--- keep original configuration while start keyguard             ---*/
769/*--------------------------------------------------------------------*/
770void kg_keep_original() {
771
772	char ifname[32];
773        char prefix[32];
774        char tmp[32];
775	char *next;
776	int unit;
777
778	for(unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; ++unit) {
779		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
780		strcpy(router_orig_wan_enable[unit], nvram_safe_get(strcat_r(prefix, "enable", tmp)));
781	}
782
783	unit = 0;
784	foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
785		snprintf(prefix, sizeof(prefix), "%d:", unit);
786		strcpy(router_orig_txchain[unit], nvram_safe_get(strcat_r(prefix, "txchain", tmp)));
787		strcpy(router_orig_rxchain[unit], nvram_safe_get(strcat_r(prefix, "rxchain", tmp)));
788		unit++;
789	}
790
791	unit = 0;
792	foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
793		snprintf(prefix, sizeof(prefix), "wl%d_", unit);
794		strcpy(router_orig_wl_radio[unit], nvram_safe_get(strcat_r(prefix, "radio", tmp)));
795		unit++;
796	}
797}
798
799
800/*--------------------------------------------------------------------*/
801/*--- stop keyguard and roll back to original configuration        ---*/
802/*--------------------------------------------------------------------*/
803void kg_restore_original() {
804	char ifname[32];
805	char *next;
806	int unit;
807
808	for(unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; ++unit) {
809
810		if(atoi(router_orig_wan_enable[unit]))
811			start_wan_if(unit);
812	}
813
814	foreach(ifname, nvram_safe_get("wl_ifnames"), next) {
815#if defined(RTCONFIG_RALINK)
816#elif defined(RTCONFIG_QCA)
817#else
818
819#if defined(RTCONFIG_QTN)
820#else
821		eval("wlconf", ifname, "down");
822		eval("wlconf", ifname, "up");
823		eval("wlconf", ifname, "start");
824#endif
825#endif
826	}
827}
828
829int keyguard_main(int argc, char *argv[])
830{
831	sigset_t sigs_to_catch;
832        sigemptyset(&sigs_to_catch);
833        sigaddset(&sigs_to_catch, SIGALRM);
834        sigaddset(&sigs_to_catch, SIGTERM);
835        sigprocmask(SIG_UNBLOCK, &sigs_to_catch, NULL);
836
837        signal(SIGALRM, kg_watchdog);
838        signal(SIGTERM, kg_exit);
839	signal(SIGUSR1, kg_update_condition);
840
841	kg_dbg = nvram_get_int("kg_debug");
842	KGINFO("KeyGuard Start...\n");
843
844	FILE *fp = fopen("/var/run/keyguard.pid", "w");
845        if(fp != NULL){
846                fprintf(fp, "%d", getpid());
847                fclose(fp);
848        }
849
850	kg_keep_original();
851	kg_init_setting();
852
853	alarmtimer(POLL_INTERVAL_SEC, 0);
854
855	while(1) {
856		pause();
857	};
858
859	return 0;
860}
861
862