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