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 2004, 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 * $Id: common_ex.c,v 1.3 2007/03/29 06:02:23 shinjung Exp $ 26 */ 27 28#include "rc.h" 29 30#include <stdlib.h> 31#include <stdio.h> 32#include <net/if_arp.h> 33#include <time.h> 34#include <bcmnvram.h> 35#include <shutils.h> 36#include <sys/time.h> 37#include <sys/ioctl.h> 38#include <sys/sysinfo.h> 39#include <stdarg.h> 40#include <arpa/inet.h> // oleg patch 41#include <string.h> // oleg patch 42#include <bcmdevs.h> 43#include <wlutils.h> 44#include <dirent.h> 45#include <sys/wait.h> 46#include <shared.h> 47 48#ifdef RTCONFIG_RALINK 49#include <ralink.h> 50#endif 51 52#ifdef RTCONFIG_QCA 53#include <qca.h> 54#endif 55 56#include <mtd.h> 57 58void update_lan_status(int); 59 60in_addr_t inet_addr_(const char *cp) 61{ 62 struct in_addr a; 63 64 if (!inet_aton(cp, &a)) 65 return INADDR_ANY; 66 else 67 return a.s_addr; 68} 69 70inline int inet_equal(char *addr1, char *mask1, char *addr2, char *mask2) 71{ 72 return ((inet_network(addr1) & inet_network(mask1)) == 73 (inet_network(addr2) & inet_network(mask2))); 74} 75 76/* remove space in the end of string */ 77char *trim_r(char *str) 78{ 79 int i; 80 81 if (!str || !*str) 82 return str; 83 84 i = strlen(str) - 1; 85 while ((i >= 0) && (str[i] == ' ' || str[i] == '\n' || str[i] == '\r')) 86 str[i--] = 0; 87 88 return str; 89} 90 91/* convert mac address format from XXXXXXXXXXXX to XX:XX:XX:XX:XX:XX */ 92char *conv_mac(char *mac, char *buf) 93{ 94 int i, j; 95 96 if (strlen(mac)==0) 97 { 98 buf[0] = 0; 99 } 100 else 101 { 102 j=0; 103 for (i=0; i<12; i++) 104 { 105 if (i!=0&&i%2==0) buf[j++] = ':'; 106 buf[j++] = mac[i]; 107 } 108 buf[j] = 0; // oleg patch 109 } 110 //buf[j] = 0; 111 112 _dprintf("mac: %s\n", buf); 113 114 return (buf); 115} 116 117// 2010.09 James. { 118/* convert mac address format from XX:XX:XX:XX:XX:XX to XXXXXXXXXXXX */ 119char *conv_mac2(char *mac, char *buf) 120{ 121 int i,j; 122 123 if(strlen(mac) != 17) 124 buf[0] = 0; 125 else{ 126 for(i = 0, j = 0; i < 17; ++i){ 127 if(i%3 != 2){ 128 buf[j] = mac[i]; 129 ++j; 130 } 131 132 buf[j] = 0; 133 } 134 } 135 136 return(buf); 137} 138 139 140/* convert mac address format from XXXXXXXXXXXX to XX:XX:XX:XX:XX:XX */ 141char *mac_conv(char *mac_name, int idx, char *buf) 142{ 143 char *mac, name[32]; 144 int i, j; 145 146 if (idx!=-1) 147 sprintf(name, "%s%d", mac_name, idx); 148 else sprintf(name, "%s", mac_name); 149 150 mac = nvram_safe_get(name); 151 152 if (strlen(mac)==0) 153 { 154 buf[0] = 0; 155 } 156 else 157 { 158 j=0; 159 for (i=0; i<12; i++) 160 { 161 if (i!=0&&i%2==0) buf[j++] = ':'; 162 buf[j++] = mac[i]; 163 } 164 buf[j] = 0; // oleg patch 165 } 166 //buf[j] = 0; 167 168 _dprintf("mac: %s\n", buf); 169 170 return (buf); 171} 172 173// 2010.09 James. { 174/* convert mac address format from XX:XX:XX:XX:XX:XX to XXXXXXXXXXXX */ 175char *mac_conv2(char *mac_name, int idx, char *buf) 176{ 177 char *mac, name[32]; 178 int i, j; 179 180 if(idx != -1) 181 sprintf(name, "%s%d", mac_name, idx); 182 else 183 sprintf(name, "%s", mac_name); 184 185 mac = nvram_safe_get(name); 186 187 if(strlen(mac) == 0 || strlen(mac) != 17) 188 buf[0] = 0; 189 else{ 190 for(i = 0, j = 0; i < 17; ++i){ 191 if(i%3 != 2){ 192 buf[j] = mac[i]; 193 ++j; 194 } 195 196 buf[j] = 0; 197 } 198 } 199 200 return(buf); 201} 202// 2010.09 James. } 203 204//#if 0 205void wan_netmask_check(void) 206{ 207 unsigned int ip, gw, nm, lip, lnm; 208 209 if (nvram_match("wan0_proto", "static") || 210 //nvram_match("wan0_proto", "pptp")) 211 nvram_match("wan0_proto", "pptp") || nvram_match("wan0_proto", "l2tp")) // oleg patch 212 { 213 ip = inet_addr(nvram_safe_get("wan_ipaddr")); 214 gw = inet_addr(nvram_safe_get("wan_gateway")); 215 nm = inet_addr(nvram_safe_get("wan_netmask")); 216 217 lip = inet_addr(nvram_safe_get("lan_ipaddr")); 218 lnm = inet_addr(nvram_safe_get("lan_netmask")); 219 220 _dprintf("ip : %x %x %x\n", ip, gw, nm); 221 222 if (ip==0x0 && (nvram_match("wan0_proto", "pptp") || nvram_match("wan0_proto", "l2tp"))) // oleg patch 223 return; 224 225 if (ip==0x0 || (ip&lnm)==(lip&lnm)) 226 { 227 nvram_set("wan_ipaddr", "1.1.1.1"); 228 nvram_set("wan_netmask", "255.0.0.0"); 229 nvram_set("wan0_ipaddr", nvram_safe_get("wan_ipaddr")); 230 nvram_set("wan0_netmask", nvram_safe_get("wan_netmask")); 231 } 232 233 // check netmask here 234 if (gw==0 || gw==0xffffffff || (ip&nm)==(gw&nm)) 235 { 236 nvram_set("wan0_netmask", nvram_safe_get("wan_netmask")); 237 } 238 else 239 { 240 for (nm=0xffffffff;nm!=0;nm=(nm>>8)) 241 { 242 if ((ip&nm)==(gw&nm)) break; 243 } 244 245 _dprintf("nm: %x\n", nm); 246 247 if (nm==0xffffffff) nvram_set("wan0_netmask", "255.255.255.255"); 248 else if (nm==0xffffff) nvram_set("wan0_netmask", "255.255.255.0"); 249 else if (nm==0xffff) nvram_set("wan0_netmask", "255.255.0.0"); 250 else if (nm==0xff) nvram_set("wan0_netmask", "255.0.0.0"); 251 else nvram_set("wan0_netmask", "0.0.0.0"); 252 } 253 254 nvram_set("wanx_ipaddr", nvram_safe_get("wan0_ipaddr")); // oleg patch, he suggests to mark the following 3 lines 255 nvram_set("wanx_netmask", nvram_safe_get("wan0_netmask")); 256 nvram_set("wanx_gateway", nvram_safe_get("wan0_gateway")); 257 } 258} 259 260/* 261 * wanmessage 262 * 263 */ 264void wanmessage(char *fmt, ...) 265{ 266 va_list args; 267 char buf[512]; 268 269 va_start(args, fmt); 270 vsnprintf(buf, sizeof(buf), fmt, args); 271 nvram_set("wan_reason_t", buf); 272 va_end(args); 273} 274 275int pppstatus(void) 276{ 277 FILE *fp; 278 char sline[128], buf[128], *p; 279 280 if ((fp = fopen("/tmp/wanstatus.log", "r")) && fgets(sline, sizeof(sline), fp)) 281 { 282 fcntl(fileno(fp), F_SETFL, fcntl(fileno(fp), F_GETFL) | O_NONBLOCK); 283 p = strstr(sline, ","); 284 strcpy(buf, p+1); 285 } 286 else 287 { 288 strcpy(buf, "unknown reason"); 289 } 290 291 if(fp) fclose(fp); 292 293 if(strstr(buf, "Failed to authenticate ourselves to peer")) return WAN_STOPPED_REASON_PPP_AUTH_FAIL; 294 else if(strstr(buf, "Terminating connection due to lack of activity")) return WAN_STOPPED_REASON_PPP_LACK_ACTIVITY; 295 else if(strstr(buf, "No response from ISP.")) return WAN_STOPPED_REASON_PPP_NO_ACTIVITY; 296 else return WAN_STOPPED_REASON_NONE; 297} 298 299void usage_exit(const char *cmd, const char *help) 300{ 301 fprintf(stderr, "Usage: %s %s\n", cmd, help); 302 exit(1); 303} 304 305#if 0 // replaced by #define in rc.h 306int modprobe(const char *mod) 307{ 308#if 1 309 return eval("modprobe", "-s", (char *)mod); 310#else 311 int r = eval("modprobe", "-s", (char *)mod); 312 cprintf("modprobe %s = %d\n", mod, r); 313 return r; 314#endif 315} 316#endif // 0 317 318int modprobe_r(const char *mod) 319{ 320#if 1 321 return eval("modprobe", "-r", (char *)mod); 322#else 323 int r = eval("modprobe", "-r", (char *)mod); 324 cprintf("modprobe -r %s = %d\n", mod, r); 325 return r; 326#endif 327} 328 329#ifndef ct_modprobe 330#ifdef LINUX26 331#define ct_modprobe(mod, args...) ({ \ 332 modprobe("nf_conntrack_"mod, ## args); \ 333 modprobe("nf_nat_"mod); \ 334}) 335#else 336#define ct_modprobe(mod, args...) ({ \ 337 modprobe("ip_conntrack_"mod, ## args); \ 338 modprobe("ip_nat_"mod, ## args); \ 339}) 340#endif 341#endif 342 343#ifndef ct_modprobe_r 344#ifdef LINUX26 345#define ct_modprobe_r(mod) ({ \ 346 modprobe_r("nf_nat_"mod); \ 347 modprobe_r("nf_conntrack_"mod); \ 348}) 349#else 350#define ct_modprobe_r(mod) ({ \ 351 modprobe_r("ip_nat_"mod); \ 352 modprobe_r("ip_conntrack_"mod); \ 353}) 354#endif 355#endif 356 357/* 358 * The various child job starting functions: 359 * _eval() 360 * Start the child. If ppid param is NULL, wait until the child exits. 361 * Otherwise, store the child's pid in ppid and return immediately. 362 * eval() 363 * Call _eval with a NULL ppid, to wait for the child to exit. 364 * xstart() 365 * Call _eval with a garbage ppid (to not wait), then return. 366 * runuserfile 367 * Execute each executable in a directory that has the specified extention. 368 * Call _eval with a ppid (to not wait), then check every second for the child's pid. 369 * After wtime seconds or when the child has exited, return. 370 * If any such filename has an '&' character in it, then do *not* wait at 371 * all for the child to exit, regardless of the wtime. 372 */ 373 374int _xstart(const char *cmd, ...) 375{ 376 va_list ap; 377 char *argv[16]; 378 int argc; 379 int pid; 380 381 argv[0] = (char *)cmd; 382 argc = 1; 383 va_start(ap, cmd); 384 while ((argv[argc++] = va_arg(ap, char *)) != NULL) { 385 // 386 } 387 va_end(ap); 388 389 return _eval(argv, NULL, 0, &pid); 390} 391 392static int endswith(const char *str, char *cmp) 393{ 394 int cmp_len, str_len, i; 395 396 cmp_len = strlen(cmp); 397 str_len = strlen(str); 398 if (cmp_len > str_len) 399 return 0; 400 for (i = 0; i < cmp_len; i++) { 401 if (str[(str_len - 1) - i] != cmp[(cmp_len - 1) - i]) 402 return 0; 403 } 404 return 1; 405} 406 407static void execute_with_maxwait(char *const argv[], int wtime) 408{ 409 pid_t pid; 410 411 if (_eval(argv, NULL, 0, &pid) != 0) 412 pid = -1; 413 else { 414 while (wtime-- > 0) { 415 waitpid(pid, NULL, WNOHANG); /* Reap the zombie if it has terminated. */ 416 if (kill(pid, 0) != 0) break; 417 sleep(1); 418 } 419 _dprintf("%s killdon: errno: %d pid %d\n", argv[0], errno, pid); 420 } 421} 422 423/* This is a bit ugly. Why didn't they allow another parameter to filter???? */ 424static char *filter_extension; 425static int endswith_filter(const struct dirent *entry) 426{ 427 return endswith(entry->d_name, filter_extension); 428} 429 430/* If the filename has an '&' character in it, don't wait at all. */ 431void run_userfile(char *folder, char *extension, const char *arg1, int wtime) 432{ 433 unsigned char buf[PATH_MAX + 1]; 434 char *argv[] = { (char *)buf, (char *)arg1, NULL }; 435 struct dirent **namelist; 436 int i, n; 437 438 /* Do them in sorted order. */ 439 filter_extension = extension; 440 n = scandir(folder, &namelist, endswith_filter, alphasort); 441 if (n >= 0) { 442 for (i = 0; i < n; ++i) { 443 sprintf((char *) buf, "%s/%s", folder, namelist[i]->d_name); 444 execute_with_maxwait(argv, 445 strchr(namelist[i]->d_name, '&') ? 0 : wtime); 446 free(namelist[i]); 447 } 448 free(namelist); 449 } 450} 451 452/* Run user-supplied script(s), with 1 argument. 453 * Return when the script(s) have finished, 454 * or after wtime seconds, even if they aren't finished. 455 * 456 * Extract NAME from nvram variable named as "script_NAME". 457 * 458 * The sole exception to the nvram item naming rule is sesx. 459 * That one is "sesx_script" rather than "script_sesx", due 460 * to historical accident. 461 * 462 * The other exception is time-scheduled commands. 463 * These have names that start with "sch_". 464 * No directories are searched for corresponding user scripts. 465 * 466 * Execute in this order: 467 * nvram item: nv (run as a /bin/sh script) 468 * (unless nv starts with a dot) 469 * All files with a suffix of ".NAME" in these directories: 470 * /etc/config/ 471 * /jffs/etc/config/ 472 * /opt/etc/config/ 473 * /mmc/etc/config/ 474 * /tmp/config/ 475 */ 476/* 477At this time, the names/events are: 478 (Unless otherwise noted, there are no parameters. Otherwise, one parameter). 479 sesx SES/AOSS Button custom script. Param: ?? 480 brau "bridge/auto" button pushed. Param: mode (bridge/auto/etc) 481 fire When firewall service has been started or re-started. 482 shut At system shutdown, just before wan/lan/usb/etc. are stopped. 483 init At system startup, just before wan/lan/usb/etc. are started. 484 The root filesystem and /jffs are mounted, but not any USB devices. 485 usbmount After an auto-mounted USB drive is mounted. 486 usbumount Before an auto-mounted USB drive is unmounted. 487 usbhotplug When any USB device is attached or removed. 488 wanup After WAN has come up. 489 autostop When a USB partition gets un-mounted. Param: the mount-point (directory). 490 If unmounted from the GUI, the directory is still mounted and accessible. 491 If the USB drive was unplugged, it is still mounted but not accessible. 492 493User scripts -- no directories are searched. One parameter. 494 autorun When a USB disk partition gets auto-mounted. Param: the mount-point (directory). 495 But not if the partition was already mounted. 496 Only the files in that directory will be run. 497*/ 498void run_nvscript(const char *nv, const char *arg1, int wtime) 499{ 500 FILE *f; 501 char *script; 502 char s[PATH_MAX + 1]; 503 char *argv[] = { s, (char *)arg1, NULL }; 504 int check_dirs = 1; 505 506 if (nv[0] == '.') { 507 strcpy(s, nv); 508 } 509 else { 510 script = nvram_get(nv); 511 512 if ((script) && (*script != 0)) { 513 sprintf(s, "/tmp/%s.sh", nv); 514 if ((f = fopen(s, "w")) != NULL) { 515 fputs("#!/bin/sh\n", f); 516 fputs(script, f); 517 fputs("\n", f); 518 fclose(f); 519 chmod(s, 0700); 520 chdir("/tmp"); 521 522 _dprintf("Running: '%s %s'\n", argv[0], argv[1]? argv[1]: ""); 523 execute_with_maxwait(argv, wtime); 524 chdir("/"); 525 } 526 } 527 528 sprintf(s, ".%s", nv); 529 if (strncmp("sch_c", nv, 5) == 0) { 530 check_dirs = 0; 531 } 532 else if (strncmp("sesx_", nv, 5) == 0) { 533 s[5] = 0; 534 } 535 else if (strncmp("script_", nv, 7) == 0) { 536 strcpy(&s[1], &nv[7]); 537 } 538 } 539 540 if (nvram_match("userfiles_disable", "1")) { 541 // backdoor to disable user scripts execution 542 check_dirs = 0; 543 } 544 545 if ((check_dirs) && strcmp(s, ".") != 0) { 546 _dprintf("checking for user scripts: '%s'\n", s); 547 run_userfile("/etc/config", s, arg1, wtime); 548 run_userfile("/jffs/etc/config", s, arg1, wtime); 549 run_userfile("/opt/etc/config", s, arg1, wtime); 550 run_userfile("/mmc/etc/config", s, arg1, wtime); 551 run_userfile("/tmp/config", s, arg1, wtime); 552 } 553} 554 555static void write_ct_timeout(const char *type, const char *name, unsigned int val) 556{ 557 unsigned char buf[128]; 558 char v[16]; 559 560 sprintf((char *) buf, "/proc/sys/net/ipv4/netfilter/ip_conntrack_%s_timeout%s%s", 561 type, (name && name[0]) ? "_" : "", name ? name : ""); 562 sprintf(v, "%u", val); 563 564 f_write_string((const char *) buf, v, 0, 0); 565} 566 567#ifndef write_tcp_timeout 568#define write_tcp_timeout(name, val) write_ct_timeout("tcp", name, val) 569#endif 570 571#ifndef write_udp_timeout 572#define write_udp_timeout(name, val) write_ct_timeout("udp", name, val) 573#endif 574 575static unsigned int read_ct_timeout(const char *type, const char *name) 576{ 577 unsigned char buf[128]; 578 unsigned int val = 0; 579 char v[16]; 580 581 sprintf((char *) buf, "/proc/sys/net/ipv4/netfilter/ip_conntrack_%s_timeout%s%s", 582 type, (name && name[0]) ? "_" : "", name ? name : ""); 583 if (f_read_string((const char *) buf, v, sizeof(v)) > 0) 584 val = atoi(v); 585 586 return val; 587} 588 589#ifndef read_tcp_timeout 590#define read_tcp_timeout(name) read_ct_timeout("tcp", name) 591#endif 592 593#ifndef read_udp_timeout 594#define read_udp_timeout(name) read_ct_timeout("udp", name) 595#endif 596 597 598void setup_ftp_conntrack(int port) 599{ 600 char ports[32]; 601 602 if(port>0&&port!=21) 603 sprintf(ports, "ports=21,%d", port); 604 else sprintf(ports, "ports=21"); 605 606 if(!nvram_match("ftp_ports", ports)) 607 { 608 ct_modprobe_r("ftp"); 609 ct_modprobe("ftp", ports); 610 nvram_set("ftp_ports", ports); 611 } 612} 613 614void setup_udp_timeout(int connflag) 615{ 616 unsigned int v[10]; 617 const char *p; 618 char buf[70]; 619 620 if (connflag 621#ifdef RTCONFIG_WIRELESSREPEATER 622 && nvram_get_int("sw_mode")!=SW_MODE_REPEATER 623#endif 624 ) { 625 p = nvram_safe_get("ct_udp_timeout"); 626 if (sscanf(p, "%u%u", &v[0], &v[1]) == 2) { 627 write_udp_timeout(NULL, v[0]); 628 write_udp_timeout("stream", v[1]); 629 } 630 else { 631 v[0] = read_udp_timeout(NULL); 632 v[1] = read_udp_timeout("stream"); 633 sprintf(buf, "%u %u", v[0], v[1]); 634 nvram_set("ct_udp_timeout", buf); 635 } 636 } 637 else { 638 write_udp_timeout(NULL, 1); 639 write_udp_timeout("stream", 6); 640 } 641} 642 643int scan_icmp_unreplied_conntrack() 644{ 645 FILE *fp = fopen( "/proc/net/nf_conntrack", "r" ); 646 char buff[1024], ipv[16], ipv_num[16], protocol[16], protocol_num[16]; 647 int found = 0; 648 649 if (fp == NULL) { 650 perror( "openning /proc/net/nf_conntrack" ); 651 return -1; 652 } 653 654 while (fgets(buff, sizeof(buff), fp) != NULL) { 655 sscanf(buff, "%s %s %s %s", ipv, ipv_num, protocol, protocol_num); 656 657 if (memcmp(protocol, "icmp", 4) || !strstr(buff, "UNREPLIED")) continue; 658 659// dbG("\n%s %s %s %s\n", ipv, ipv_num, protocol, protocol_num); 660 661 found++; 662 break; 663 } 664 665 fclose(fp); 666 667// if (!found) 668// dbG("No matching conntrack found\n"); 669 670 return found; 671} 672 673void setup_ct_timeout(int connflag) 674{ 675 unsigned int v[10]; 676 const char *p; 677 char buf[70]; 678 int i; 679 680 if (connflag 681#ifdef RTCONFIG_WIRELESSREPEATER 682 && nvram_get_int("sw_mode")!=SW_MODE_REPEATER 683#endif 684 ) { 685 p = nvram_safe_get("ct_timeout"); 686 if (sscanf(p, "%u%u", &v[0], &v[1]) == 2) { 687// write_ct_timeout("generic", NULL, v[0]); 688 write_ct_timeout("icmp", NULL, v[1]); 689 } 690 else { 691 v[0] = read_ct_timeout("generic", NULL); 692 v[1] = read_ct_timeout("icmp", NULL); 693 694 sprintf(buf, "%u %u", v[0], v[1]); 695 nvram_set("ct_timeout", buf); 696 } 697 } 698 else { 699 for (i = 0; i < 3; i++) 700 { 701 if (scan_icmp_unreplied_conntrack() > 0) 702 { 703// write_ct_timeout("generic", NULL, 0); 704 write_ct_timeout("icmp", NULL, 0); 705 sleep(2); 706 } 707 } 708 } 709} 710 711void setup_conntrack(void) 712{ 713 unsigned int v[10]; 714 const char *p; 715 char buf[70]; 716 int i; 717 718 p = nvram_safe_get("ct_tcp_timeout"); 719 if (sscanf(p, "%u%u%u%u%u%u%u%u%u%u", 720 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], &v[9]) == 10) { // lightly verify 721 write_tcp_timeout("established", v[1]); 722 write_tcp_timeout("syn_sent", v[2]); 723 write_tcp_timeout("syn_recv", v[3]); 724 write_tcp_timeout("fin_wait", v[4]); 725 write_tcp_timeout("time_wait", v[5]); 726 write_tcp_timeout("close", v[6]); 727 write_tcp_timeout("close_wait", v[7]); 728 write_tcp_timeout("last_ack", v[8]); 729 } 730 else { 731 v[1] = read_tcp_timeout("established"); 732 v[2] = read_tcp_timeout("syn_sent"); 733 v[3] = read_tcp_timeout("syn_recv"); 734 v[4] = read_tcp_timeout("fin_wait"); 735 v[5] = read_tcp_timeout("time_wait"); 736 v[6] = read_tcp_timeout("close"); 737 v[7] = read_tcp_timeout("close_wait"); 738 v[8] = read_tcp_timeout("last_ack"); 739 sprintf(buf, "0 %u %u %u %u %u %u %u %u 0", 740 v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); 741 nvram_set("ct_tcp_timeout", buf); 742 } 743 744 setup_udp_timeout(FALSE); 745 746 p = nvram_safe_get("ct_timeout"); 747 if (sscanf(p, "%u%u", &v[0], &v[1]) == 2) { 748// write_ct_timeout("generic", NULL, v[0]); 749 write_ct_timeout("icmp", NULL, v[1]); 750 } 751 else { 752 v[0] = read_ct_timeout("generic", NULL); 753 v[1] = read_ct_timeout("icmp", NULL); 754 sprintf(buf, "%u %u", v[0], v[1]); 755 nvram_set("ct_timeout", buf); 756 } 757 758#ifdef LINUX26 759 p = nvram_safe_get("ct_hashsize"); 760 i = atoi(p); 761 if (i >= 127) { 762 f_write_string("/sys/module/nf_conntrack/parameters/hashsize", p, 0, 0); 763 } 764 else if (f_read_string("/sys/module/nf_conntrack/parameters/hashsize", buf, sizeof(buf)) > 0) { 765 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; 766 if (atoi(buf) > 0) nvram_set("ct_hashsize", buf); 767 } 768#endif 769#ifdef LINUX26 770 p = nvram_safe_get("ct_max"); 771 i = atoi(p); 772 if (i >= 128) { 773 f_write_string("/proc/sys/net/nf_conntrack_max", p, 0, 0); 774 } 775 else if (f_read_string("/proc/sys/net/nf_conntrack_max", buf, sizeof(buf)) > 0) { 776 if (atoi(buf) > 0) nvram_set("ct_max", buf); 777 } 778#else 779 p = nvram_safe_get("ct_max"); 780 i = atoi(p); 781 if (i >= 128) { 782 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_max", p, 0, 0); 783 } 784 else if (f_read_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_max", buf, sizeof(buf)) > 0) { 785 if (atoi(buf) > 0) nvram_set("ct_max", buf); 786 } 787#endif 788#if 0 789 if (!nvram_match("nf_rtsp", "0")) { 790 ct_modprobe("rtsp"); 791 } 792 else { 793 ct_modprobe_r("rtsp"); 794 } 795 796 if (!nvram_match("nf_h323", "0")) { 797 ct_modprobe("h323"); 798 } 799 else { 800 ct_modprobe_r("h323"); 801 } 802 803#ifdef LINUX26 804 if (!nvram_match("nf_sip", "0")) { 805 ct_modprobe("sip"); 806 } 807 else { 808 ct_modprobe_r("sip"); 809 } 810#endif 811#endif 812 // !!TB - FTP Server 813#ifdef RTCONFIG_FTP 814 i = nvram_get_int("ftp_port"); 815 if (nvram_match("ftp_enable", "1") && (i > 0) && (i != 21)) 816 { 817 char ports[32]; 818 819 sprintf(ports, "ports=21,%d", i); 820 ct_modprobe("ftp", ports); 821 } 822 else 823#endif 824 if (!nvram_match("nf_ftp", "0") 825#ifdef RTCONFIG_FTP 826 || nvram_match("ftp_enable", "1") // !!TB - FTP Server 827#endif 828 ) { 829 ct_modprobe("ftp"); 830 } 831 else { 832 ct_modprobe_r("ftp"); 833 } 834 835 if (!nvram_match("nf_pptp", "0")) { 836 ct_modprobe("proto_gre"); 837 ct_modprobe("pptp"); 838 } 839 else { 840 ct_modprobe_r("pptp"); 841 ct_modprobe_r("proto_gre"); 842 } 843} 844 845void setup_pt_conntrack(void) 846{ 847 if (!nvram_match("fw_pt_rtsp", "0")) { 848 ct_modprobe("rtsp", "ports=554,8554"); 849 } 850 else { 851 ct_modprobe_r("rtsp"); 852 } 853 854 if (!nvram_match("fw_pt_h323", "0")) { 855 ct_modprobe("h323"); 856 } 857 else { 858 ct_modprobe_r("h323"); 859 } 860 861#ifdef LINUX26 862 if (!nvram_match("fw_pt_sip", "0")) { 863 ct_modprobe("sip"); 864 } 865 else { 866 ct_modprobe_r("sip"); 867 } 868#endif 869} 870 871void remove_conntrack(void) 872{ 873 ct_modprobe_r("pptp"); 874 ct_modprobe_r("ftp"); 875 ct_modprobe_r("rtsp"); 876 ct_modprobe_r("h323"); 877#ifdef LINUX26 878 ct_modprobe_r("sip"); 879#endif 880} 881 882void inc_mac(char *mac, int plus) 883{ 884 unsigned char m[6]; 885 int i; 886 887 for (i = 0; i < 6; i++) 888 m[i] = (unsigned char) strtol(mac + (3 * i), (char **)NULL, 16); 889 while (plus != 0) { 890 for (i = 5; i >= 3; --i) { 891 m[i] += (plus < 0) ? -1 : 1; 892 if (m[i] != 0) break; // continue if rolled over 893 } 894 plus += (plus < 0) ? 1 : -1; 895 } 896 sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", 897 m[0], m[1], m[2], m[3], m[4], m[5]); 898} 899 900void set_mac(const char *ifname, const char *nvname, int plus) 901{ 902 int sfd; 903 struct ifreq ifr; 904 int up; 905 int j; 906 char *et_hwaddr = NULL; 907 908 if ((sfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { 909 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__); 910 return; 911 } 912 913 strcpy(ifr.ifr_name, ifname); 914 915 up = 0; 916 if (ioctl(sfd, SIOCGIFFLAGS, &ifr) == 0) { 917 if ((up = ifr.ifr_flags & IFF_UP) != 0) { 918 ifr.ifr_flags &= ~IFF_UP; 919 if (ioctl(sfd, SIOCSIFFLAGS, &ifr) != 0) { 920 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__); 921 } 922 } 923 } 924 else { 925 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__); 926 } 927#ifdef RTCONFIG_RGMII_BRCM5301X 928 et_hwaddr = nvram_safe_get("lan_hwaddr"); 929#elif defined(RTCONFIG_GMAC3) 930 if (nvram_match("gmac3_enable", "1")) 931 et_hwaddr = nvram_safe_get("et2macaddr"); 932 else 933 et_hwaddr = nvram_safe_get("et0macaddr"); 934#else 935 et_hwaddr = nvram_safe_get("et0macaddr"); 936#endif 937 938 if (!ether_atoe(nvram_safe_get(nvname), (unsigned char *)&ifr.ifr_hwaddr.sa_data)) { 939 if (!ether_atoe(et_hwaddr, (unsigned char *)&ifr.ifr_hwaddr.sa_data)) { 940 941 // goofy et0macaddr, make something up 942#ifdef RTCONFIG_RGMII_BRCM5301X 943 nvram_set("lan_hwaddr", "00:01:23:45:67:89"); 944#elif defined(RTCONFIG_GMAC3) 945 if (nvram_match("gmac3_enable", "1")) 946 nvram_set("et2macaddr", "00:01:23:45:67:89"); 947 else 948 nvram_set("et0macaddr", "00:01:23:45:67:89"); 949#else 950 nvram_set("et0macaddr", "00:01:23:45:67:89"); 951#endif 952 ifr.ifr_hwaddr.sa_data[0] = 0; 953 ifr.ifr_hwaddr.sa_data[1] = 0x01; 954 ifr.ifr_hwaddr.sa_data[2] = 0x23; 955 ifr.ifr_hwaddr.sa_data[3] = 0x45; 956 ifr.ifr_hwaddr.sa_data[4] = 0x67; 957 ifr.ifr_hwaddr.sa_data[5] = 0x89; 958 } 959 960 while (plus-- > 0) { 961 for (j = 5; j >= 3; --j) { 962 ifr.ifr_hwaddr.sa_data[j]++; 963 if (ifr.ifr_hwaddr.sa_data[j] != 0) break; // continue if rolled over 964 } 965 } 966 } 967 968 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 969 if (ioctl(sfd, SIOCSIFHWADDR, &ifr) == -1) { 970 _dprintf("Error setting %s address\n", ifname); 971 } 972 973 if (up) { 974 if (ioctl(sfd, SIOCGIFFLAGS, &ifr) == 0) { 975 ifr.ifr_flags |= IFF_UP|IFF_RUNNING; 976 if (ioctl(sfd, SIOCSIFFLAGS, &ifr) == -1) { 977 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__); 978 } 979 } 980 else { 981 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__); 982 } 983 } 984 985 close(sfd); 986} 987 988/* 989const char *default_wanif(void) 990{ 991 return ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) || 992 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1"; 993} 994*/ 995 996/* 997const char *default_wlif(void) 998{ 999 switch (check_hw_type()) { 1000 case HW_BCM4702: 1001 case HW_BCM4704_BCM5325F: 1002 case HW_BCM4704_BCM5325F_EWC: 1003 return "eth2"; 1004 } 1005 return "eth1"; 1006 1007} 1008*/ 1009 1010void simple_unlock(const char *name) 1011{ 1012 char fn[256]; 1013 1014 snprintf(fn, sizeof(fn), "/var/lock/%s.lock", name); 1015 f_write(fn, NULL, 0, 0, 0600); 1016} 1017 1018void simple_lock(const char *name) 1019{ 1020 int n; 1021 char fn[256]; 1022 1023 n = 5 + (getpid() % 10); 1024 snprintf(fn, sizeof(fn), "/var/lock/%s.lock", name); 1025 while (unlink(fn) != 0) { 1026 if (--n == 0) { 1027 syslog(LOG_DEBUG, "Breaking %s", fn); 1028 break; 1029 } 1030 sleep(1); 1031 } 1032} 1033 1034void killall_tk(const char *name) 1035{ 1036 int n; 1037 1038 if (killall(name, SIGTERM) == 0) { 1039 n = 10; 1040 while ((killall(name, 0) == 0) && (n-- > 0)) { 1041 _dprintf("%s: waiting name=%s n=%d\n", __FUNCTION__, name, n); 1042 usleep(100 * 1000); 1043 } 1044 if (n < 0) { 1045 n = 10; 1046 while ((killall(name, SIGKILL) == 0) && (n-- > 0)) { 1047 _dprintf("%s: SIGKILL name=%s n=%d\n", __FUNCTION__, name, n); 1048 usleep(100 * 1000); 1049 } 1050 } 1051 } 1052} 1053 1054void kill_pidfile_tk(const char *pidfile) 1055{ 1056 FILE *fp; 1057 char buf[256]; 1058 pid_t pid = 0; 1059 int n; 1060 1061 if ((fp = fopen(pidfile, "r")) != NULL) { 1062 if (fgets(buf, sizeof(buf), fp) != NULL) 1063 pid = strtoul(buf, NULL, 0); 1064 fclose(fp); 1065 } 1066 1067 if (pid > 1 && kill(pid, SIGTERM) == 0) { 1068 n = 10; 1069 while ((kill(pid, 0) == 0) && (n-- > 0)) { 1070 _dprintf("%s: waiting pid=%d n=%d\n", __FUNCTION__, pid, n); 1071 usleep(100 * 1000); 1072 } 1073 if (n < 0) { 1074 n = 10; 1075 while ((kill(pid, SIGKILL) == 0) && (n-- > 0)) { 1076 _dprintf("%s: SIGKILL pid=%d n=%d\n", __FUNCTION__, pid, n); 1077 usleep(100 * 1000); 1078 } 1079 } 1080 } 1081} 1082 1083long fappend(FILE *out, const char *fname) 1084{ 1085 FILE *in; 1086 char buf[1024]; 1087 int n; 1088 long r; 1089 1090 if ((in = fopen(fname, "r")) == NULL) return -1; 1091 r = 0; 1092 while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { 1093 if (fwrite(buf, 1, n, out) != n) { 1094 r = -1; 1095 break; 1096 } 1097 else { 1098 r += n; 1099 } 1100 } 1101 fclose(in); 1102 return r; 1103} 1104 1105long fappend_file(const char *path, const char *fname) 1106{ 1107 FILE *f; 1108 int r = -1; 1109 1110 if (f_exists(fname) && (f = fopen(path, "a")) != NULL) { 1111 r = fappend(f, fname); 1112 fclose(f); 1113 } 1114 return r; 1115} 1116 1117/* uclibc accepts any of following: 1118 * [STD][Offset][DST], where 1119 * [STD] ~ any [a-zA-Z] 1120 * [DST] ~ any [a-zA-Z] */ 1121#define CONVERT_TZ_TO_GMT_DST 1122#ifdef CONVERT_TZ_TO_GMT_DST 1123int gettzoffset(char *tzstr, char *tzstr1, int size1) 1124{ 1125 char offstr[32]; 1126 char *tzptr = tzstr; 1127 char *offptr = offstr; 1128 int ret = 0; 1129 int dst = 0; 1130 1131 memset(offstr, 0, sizeof(offstr)); 1132 for ( ; *tzptr; tzptr++) { 1133 if (*tzptr=='-'||*tzptr=='+'||*tzptr==':'||isdigit(*tzptr)) { 1134 *offptr++ = *tzptr; 1135 ret = 1; 1136 } else if (ret) { 1137 dst = isalpha(*tzptr); 1138 break; 1139 } 1140 } 1141 1142 if (ret) 1143 snprintf(tzstr1, size1, "GMT%s%s", offstr, dst ? "DST" : ""); 1144 return ret; 1145} 1146#endif 1147 1148void time_zone_x_mapping(void) 1149{ 1150 FILE *fp; 1151 char tmpstr[32]; 1152 char *ptr; 1153 1154 /* pre mapping */ 1155 if (nvram_match("time_zone", "KST-9KDT")) 1156 nvram_set("time_zone", "UCT-9_1"); 1157 else if (nvram_match("time_zone", "RFT-9RFTDST")) 1158 nvram_set("time_zone", "UCT-9_2"); 1159 else if (nvram_match("time_zone", "UTC-2DST_1")) /*Minsk*/ 1160 nvram_set("time_zone", "UTC-3_3"); 1161 else if (nvram_match("time_zone", "UTC-4_2")) /*Moscow, St. Petersburg*/ 1162 nvram_set("time_zone", "UTC-3_4"); 1163 else if (nvram_match("time_zone", "UTC-4_3")) /*Volgograd*/ 1164 nvram_set("time_zone", "UTC-3_5"); 1165 else if (nvram_match("time_zone", "UTC-6_1")) /*Yekaterinburg*/ 1166 nvram_set("time_zone", "UTC-5_1"); 1167 else if (nvram_match("time_zone", "UTC-7_1")) /*Novosibirsk*/ 1168 nvram_set("time_zone", "UTC-6_2"); 1169 else if (nvram_match("time_zone", "CST-8_2")) /*Krasnoyarsk*/ 1170 nvram_set("time_zone", "CST-7_2"); 1171 else if (nvram_match("time_zone", "UTC-9_2")) /*Irkutsk*/ 1172 nvram_set("time_zone", "UTC-8_1"); 1173 else if (nvram_match("time_zone", "UTC-10_3")) /*Yakutsk*/ 1174 nvram_set("time_zone", "UTC-9_3"); 1175 else if (nvram_match("time_zone", "UTC-11_2")) /*Vladivostok*/ 1176 nvram_set("time_zone", "UTC-10_4"); 1177 else if (nvram_match("time_zone", "UTC-12_1")) /*Magadan*/ 1178 nvram_set("time_zone", "UTC-10_5"); 1179 1180 snprintf(tmpstr, sizeof(tmpstr), "%s", nvram_safe_get("time_zone")); 1181 /* replace . with : */ 1182 while ((ptr=strchr(tmpstr, '.'))!=NULL) *ptr = ':'; 1183 /* remove *_? */ 1184 while ((ptr=strchr(tmpstr, '_'))!=NULL) *ptr = 0x0; 1185 1186 /* check time_zone_dst for daylight saving */ 1187 if (nvram_get_int("time_zone_dst")) 1188 sprintf(tmpstr, "%s,%s", tmpstr, nvram_safe_get("time_zone_dstoff")); 1189#ifdef CONVERT_TZ_TO_GMT_DST 1190 else gettzoffset(tmpstr, tmpstr, sizeof(tmpstr)); 1191#endif 1192 1193 nvram_set("time_zone_x", tmpstr); 1194 1195 /* special mapping */ 1196 if (nvram_match("time_zone", "JST")) 1197 nvram_set("time_zone_x", "UCT-9"); 1198#if 0 1199 else if (nvram_match("time_zone", "TST-10TDT")) 1200 nvram_set("time_zone_x", "UCT-10"); 1201 else if (nvram_match("time_zone", "CST-9:30CDT")) 1202 nvram_set("time_zone_x", "UCT-9:30"); 1203#endif 1204 1205 if ((fp = fopen("/etc/TZ", "w")) != NULL) { 1206 fprintf(fp, "%s\n", tmpstr); 1207 fclose(fp); 1208 } 1209} 1210 1211/* Get the timezone from NVRAM and set the timezone in the kernel 1212 * and export the TZ variable 1213 */ 1214void 1215setup_timezone(void) 1216{ 1217#ifndef RC_BUILDTIME 1218#define RC_BUILDTIME 1438387200 // Aug 1 00:00:00 GMT 2015 1219#endif 1220 time_t now; 1221 struct tm gm, local; 1222 struct timezone tz; 1223 struct timeval tv = { RC_BUILDTIME, 0 }; 1224 struct timeval *tvp = NULL; 1225 1226 /* Export TZ variable for the time libraries to 1227 * use. 1228 */ 1229 time_zone_x_mapping(); 1230 setenv("TZ", nvram_get("time_zone_x"), 1); 1231 1232 /* Update kernel timezone */ 1233 time(&now); 1234 gmtime_r(&now, &gm); 1235 localtime_r(&now, &local); 1236 gm.tm_isdst = local.tm_isdst; 1237 tz.tz_minuteswest = (mktime(&gm) - mktime(&local)) / 60; 1238 1239 /* Setup sane start time */ 1240 if (now < RC_BUILDTIME) { 1241 struct sysinfo info; 1242 1243 sysinfo(&info); 1244 tv.tv_sec += info.uptime; 1245 tvp = &tv; 1246 } 1247 1248 settimeofday(tvp, &tz); 1249} 1250 1251int 1252is_invalid_char_for_hostname(char c) 1253{ 1254 int ret = 0; 1255 1256 if (c < 0x20) 1257 ret = 1; 1258#if 0 1259 else if (c >= 0x21 && c <= 0x2c) /* !"#$%&'()*+, */ 1260 ret = 1; 1261#else /* allow '+' */ 1262 else if (c >= 0x21 && c <= 0x2a) /* !"#$%&'()* */ 1263 ret = 1; 1264 else if (c == 0x2c) /* , */ 1265 ret = 1; 1266#endif 1267 else if (c >= 0x2e && c <= 0x2f) /* ./ */ 1268 ret = 1; 1269 else if (c >= 0x3a && c <= 0x40) /* :;<=>?@ */ 1270 ret = 1; 1271#if 0 1272 else if (c >= 0x5b && c <= 0x60) /* [\]^_ */ 1273 ret = 1; 1274#else /* allow '_' */ 1275 else if (c >= 0x5b && c <= 0x5e) /* [\]^ */ 1276 ret = 1; 1277 else if (c == 0x60) /* ` */ 1278 ret = 1; 1279#endif 1280 else if (c >= 0x7b) /* {|}~ DEL */ 1281 ret = 1; 1282#if 0 1283 printf("%c (0x%02x) is %svalid for hostname\n", c, c, (ret == 0) ? " " : "in"); 1284#endif 1285 return ret; 1286} 1287 1288int 1289is_valid_hostname(const char *name) 1290{ 1291 int len, i; 1292 1293 if (!name) 1294 return 0; 1295 1296 len = strlen(name); 1297 for (i = 0; i < len ; i++) { 1298 if (is_invalid_char_for_hostname(name[i])) { 1299 len = 0; 1300 break; 1301 } 1302 } 1303#if 0 1304 printf("%s is %svalid for hostname\n", name, len ? "" : "in"); 1305#endif 1306 return len; 1307} 1308 1309int get_meminfo_item(const char *name) 1310{ 1311 FILE *fp; 1312 char memdata[256] = {0}; 1313 int mem = 0; 1314 1315 if (!name || *name == '\0') 1316 return -1; 1317 1318 if ((fp = fopen("/proc/meminfo", "r")) != NULL) { 1319 /* get one memory parameter specified by the name */ 1320 while (fgets(memdata, 255, fp) != NULL) { 1321 if (strstr(memdata, name) != NULL) { 1322 sscanf(memdata, "%*s %d kB", &mem); 1323 break; 1324 } 1325 } 1326 fclose(fp); 1327 } 1328 1329 return mem; 1330} 1331 1332#ifdef RTCONFIG_SHP 1333void restart_lfp() 1334{ 1335 char v[32]; 1336 1337 if(nvram_get_int("lfp_disable")==0) { 1338 sprintf(v, "%x", inet_addr(nvram_safe_get("lan_ipaddr"))); 1339 f_write_string("/proc/net/lfpctrl", v, 0, 0); 1340 } 1341 else { 1342 f_write_string("/proc/net/lfpctrl", "", 0, 0); 1343 } 1344} 1345#endif 1346 1347#ifdef CONFIG_BCMWL5 1348int setup_dnsmq(int mode) 1349{ 1350 char v[32]; 1351 char tmp[32]; 1352 1353 if(mode) { 1354 // setup ebtables 1355 eval("ebtables", "-F"); 1356 eval("ebtables", "-t", "broute", "-F"); 1357 eval("ebtables", "-t", "broute", "-I", "BROUTING", "-d", "00:E0:11:22:33:44", "-j", "redirect", "--redirect-target", "DROP"); 1358 } 1359 else { 1360 eval("ebtables", "-F"); 1361 eval("ebtables", "-t", "broute", "-F"); 1362 eval("ebtables", "-I", "FORWARD", "-i", "eth1", "-j", "DROP"); 1363 } 1364 1365 eval("iptables", "-t", "nat", "-F", "PREROUTING"); 1366 eval("iptables", "-t", "nat", "-I", "PREROUTING", "-p", "udp", "--dport", "53", 1367 "-j", "DNAT", "--to-destination", strcat_r(nvram_safe_get("lan_ipaddr"), ":18018", tmp)); 1368 1369 if(mode) { 1370#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA) 1371 if (!is_psta(nvram_get_int("wlc_band")) && !is_psr(nvram_get_int("wlc_band"))) 1372#endif 1373 snprintf(tmp, sizeof(tmp), "%s:%d", nvram_safe_get("lan_ipaddr"), /*nvram_get_int("http_lanport") ? :*/ 80); 1374 eval("iptables", "-t", "nat", "-I", "PREROUTING", "-p", "tcp", "-d", "10.0.0.1", "--dport", "80", 1375 "-j", "DNAT", "--to-destination", tmp); 1376 1377 //sprintf(v, "%x my.%s", inet_addr("10.0.0.1"), get_productid()); 1378 sprintf(v, "%x %s", inet_addr(nvram_safe_get("lan_ipaddr")), DUT_DOMAIN_NAME); 1379 f_write_string("/proc/net/dnsmqctrl", v, 0, 0); 1380 } 1381 else { 1382 // setup ebtables and iptables 1383#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA) 1384 if (!is_psta(nvram_get_int("wlc_band")) && !is_psr(nvram_get_int("wlc_band"))) 1385#endif 1386 eval("iptables", "-t", "nat", "-I", "PREROUTING", "-p", "tcp", "-d", "10.0.0.1", "--dport", "80", 1387 "-j", "DNAT", "--to-destination", strcat_r(nvram_safe_get("lan_ipaddr"), ":18017", tmp)); 1388 1389 f_write_string("/proc/net/dnsmqctrl", "", 0, 0); 1390 } 1391 1392 return 0; 1393} 1394#endif 1395 1396void stop_if_misc(void) 1397{ 1398 DIR *dir; 1399 struct dirent *dirent; 1400 struct ifreq ifr; 1401 int sfd; 1402 1403 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) { 1404 while ((dirent = readdir(dir)) != NULL) { 1405 if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) 1406 continue; 1407 1408 if (strcmp(dirent->d_name, "all") && 1409 strcmp(dirent->d_name, "default") && 1410 strcmp(dirent->d_name, "lo") && 1411 strncmp(dirent->d_name, "br", 2) && 1412 strncmp(dirent->d_name, "eth", 3) && 1413 strncmp(dirent->d_name, "ra", 2) && 1414 !((sfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)) 1415 { 1416 strcpy(ifr.ifr_name, dirent->d_name); 1417 if (!ioctl(sfd, SIOCGIFFLAGS, &ifr) && (ifr.ifr_flags & IFF_UP)) 1418 ifconfig(ifr.ifr_name, 0, NULL, NULL); 1419 1420 close(sfd); 1421 } 1422 1423 } 1424 closedir(dir); 1425 } 1426} 1427 1428int mssid_mac_validate(const char *macaddr) 1429{ 1430 unsigned char mac_binary[6]; 1431 unsigned long long macvalue; 1432 char macbuf[13]; 1433 1434 if (!macaddr || !strlen(macaddr)) 1435 return 0; 1436 1437 ether_atoe(macaddr, mac_binary); 1438 sprintf(macbuf, "%02X%02X%02X%02X%02X%02X", 1439 mac_binary[0], 1440 mac_binary[1], 1441 mac_binary[2], 1442 mac_binary[3], 1443 mac_binary[4], 1444 mac_binary[5]); 1445 macvalue = strtoll(macbuf, (char **) NULL, 16); 1446 if (macvalue % 4) 1447 return 0; 1448 else 1449 return 1; 1450} 1451