Web monitor: add GUI and iptables support
[tomato.git] / release / src / router / rc / init.c
blobfa414932f7633a5b25896bf30ea73485828e92df
1 /*
3 Copyright 2005, Broadcom Corporation
4 All Rights Reserved.
6 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
7 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
8 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13 #include "rc.h"
15 #include <termios.h>
16 #include <dirent.h>
17 #include <sys/ioctl.h>
18 #include <sys/mount.h>
19 #include <time.h>
20 #include <errno.h>
21 #include <paths.h>
22 #include <sys/wait.h>
23 #include <sys/reboot.h>
24 #include <sys/klog.h>
25 #ifdef LINUX26
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/sysinfo.h>
29 #endif
30 #include <wlutils.h>
31 #include <bcmdevs.h>
33 #define SHELL "/bin/sh"
36 enum {
37 RESTART,
38 STOP,
39 START,
40 USER1,
41 IDLE,
42 REBOOT,
43 HALT,
44 INIT
47 static int fatalsigs[] = {
48 SIGILL,
49 SIGABRT,
50 SIGFPE,
51 SIGPIPE,
52 SIGBUS,
53 SIGSYS,
54 SIGTRAP,
55 SIGPWR
58 static int initsigs[] = {
59 SIGHUP,
60 SIGUSR1,
61 SIGUSR2,
62 SIGINT,
63 SIGQUIT,
64 SIGTERM
67 static char *defenv[] = {
68 "TERM=vt100",
69 "HOME=/",
70 "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
71 "SHELL=" SHELL,
72 "USER=root",
73 NULL
76 static int noconsole = 0;
77 static volatile int state = INIT;
78 static volatile int signaled = -1;
81 /* Set terminal settings to reasonable defaults */
82 static void set_term(int fd)
84 struct termios tty;
86 tcgetattr(fd, &tty);
88 /* set control chars */
89 tty.c_cc[VINTR] = 3; /* C-c */
90 tty.c_cc[VQUIT] = 28; /* C-\ */
91 tty.c_cc[VERASE] = 127; /* C-? */
92 tty.c_cc[VKILL] = 21; /* C-u */
93 tty.c_cc[VEOF] = 4; /* C-d */
94 tty.c_cc[VSTART] = 17; /* C-q */
95 tty.c_cc[VSTOP] = 19; /* C-s */
96 tty.c_cc[VSUSP] = 26; /* C-z */
98 /* use line dicipline 0 */
99 tty.c_line = 0;
101 /* Make it be sane */
102 tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
103 tty.c_cflag |= CREAD|HUPCL|CLOCAL;
106 /* input modes */
107 tty.c_iflag = ICRNL | IXON | IXOFF;
109 /* output modes */
110 tty.c_oflag = OPOST | ONLCR;
112 /* local modes */
113 tty.c_lflag =
114 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
116 tcsetattr(fd, TCSANOW, &tty);
119 static int console_init(void)
121 int fd;
123 /* Clean up */
124 ioctl(0, TIOCNOTTY, 0);
125 close(0);
126 close(1);
127 close(2);
128 setsid();
130 /* Reopen console */
131 if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) {
132 /* Avoid debug messages is redirected to socket packet if no exist a UART chip, added by honor, 2003-12-04 */
133 open("/dev/null", O_RDONLY);
134 open("/dev/null", O_WRONLY);
135 open("/dev/null", O_WRONLY);
136 perror(_PATH_CONSOLE);
137 return errno;
139 dup2(fd, 0);
140 dup2(fd, 1);
141 dup2(fd, 2);
143 ioctl(0, TIOCSCTTY, 1);
144 tcsetpgrp(0, getpgrp());
145 set_term(0);
147 return 0;
151 * Waits for a file descriptor to change status or unblocked signal
152 * @param fd file descriptor
153 * @param timeout seconds to wait before timing out or 0 for no timeout
154 * @return 1 if descriptor changed status or 0 if timed out or -1 on error
156 static int waitfor(int fd, int timeout)
158 fd_set rfds;
159 struct timeval tv = { timeout, 0 };
161 FD_ZERO(&rfds);
162 FD_SET(fd, &rfds);
163 return select(fd + 1, &rfds, NULL, NULL, (timeout > 0) ? &tv : NULL);
166 static pid_t run_shell(int timeout, int nowait)
168 pid_t pid;
169 int sig;
171 /* Wait for user input */
172 if (waitfor(STDIN_FILENO, timeout) <= 0) return 0;
174 switch (pid = fork()) {
175 case -1:
176 perror("fork");
177 return 0;
178 case 0:
179 /* Reset signal handlers set for parent process */
180 for (sig = 0; sig < (_NSIG-1); sig++)
181 signal(sig, SIG_DFL);
183 /* Reopen console */
184 console_init();
185 printf("\n\nTomato %s\n\n", tomato_version);
187 /* Now run it. The new program will take over this PID,
188 * so nothing further in init.c should be run. */
189 execve(SHELL, (char *[]) { SHELL, NULL }, defenv);
191 /* We're still here? Some error happened. */
192 perror(SHELL);
193 exit(errno);
194 default:
195 if (nowait) {
196 return pid;
198 else {
199 waitpid(pid, NULL, 0);
200 return 0;
205 static void shutdn(int rb)
207 int i;
208 int act;
209 sigset_t ss;
211 _dprintf("shutdn rb=%d\n", rb);
213 sigemptyset(&ss);
214 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++)
215 sigaddset(&ss, fatalsigs[i]);
216 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++)
217 sigaddset(&ss, initsigs[i]);
218 sigaddset(&ss, SIGCHLD);
219 sigprocmask(SIG_BLOCK, &ss, NULL);
221 for (i = 30; i > 0; --i) {
222 if (((act = check_action()) == ACT_IDLE) || (act == ACT_REBOOT)) break;
223 cprintf("Busy with %d. Waiting before shutdown... %d\n", act, i);
224 sleep(1);
226 set_action(ACT_REBOOT);
228 cprintf("TERM\n");
229 kill(-1, SIGTERM);
230 sleep(2);
231 sync();
233 cprintf("KILL\n");
234 kill(-1, SIGKILL);
235 sleep(1);
236 sync();
238 umount("/jffs"); // may hang if not
239 sleep(1);
241 if (rb != -1) {
242 led(LED_WLAN, 0);
243 if (rb == 0) {
244 for (i = 4; i > 0; --i) {
245 led(LED_DMZ, 1);
246 led(LED_WHITE, 1);
247 usleep(250000);
248 led(LED_DMZ, 0);
249 led(LED_WHITE, 0);
250 usleep(250000);
255 reboot(rb ? RB_AUTOBOOT : RB_HALT_SYSTEM);
257 do {
258 sleep(1);
259 } while (1);
262 static void handle_fatalsigs(int sig)
264 _dprintf("fatal sig=%d\n", sig);
265 shutdn(-1);
268 void handle_reap(int sig)
270 while (waitpid(-1, NULL, WNOHANG) > 0) {
275 static void handle_initsigs(int sig)
277 // TRACE_PT("sig=%d state=%d, signaled=%d\n", sig, state, signaled);
279 switch (sig) {
280 case SIGHUP:
281 signaled = RESTART;
282 break;
283 case SIGUSR1:
284 signaled = USER1;
285 break;
286 case SIGUSR2:
287 signaled = START;
288 break;
289 case SIGINT:
290 signaled = STOP;
291 break;
292 case SIGTERM:
293 signaled = REBOOT;
294 break;
295 case SIGQUIT:
296 signaled = HALT;
297 break;
301 static int check_nv(const char *name, const char *value)
303 const char *p;
304 if (!nvram_match("manual_boot_nv", "1")) {
305 if (((p = nvram_get(name)) == NULL) || (strcmp(p, value) != 0)) {
306 // cprintf("Error: Critical variable %s is invalid. Resetting.\n", name);
307 nvram_set(name, value);
308 return 1;
311 return 0;
314 static int find_dir320_mac_addr()
316 FILE *fp;
317 char *buffer, s[18];
318 int i, part, size, found = 0;
320 if (!mtd_getinfo("board_data", &part, &size)) return 0;
321 sprintf(s, MTD_DEV(%dro), part);
323 fp = fopen(s, "rb");
324 if (fp != NULL) {
325 buffer = malloc(size);
326 memset(buffer, 0, size);
327 fread(buffer, size, 1, fp);
328 if (!memcmp(buffer, "RGCFG1", 6)) {
329 for (i = 6; i < size - 24; i++) {
330 if (!memcmp(buffer + i, "lanmac=", 7)) {
331 memcpy(s, buffer + i + 7, 17);
332 s[17] = 0;
333 nvram_set("il0macaddr", s);
335 else if (!memcmp(buffer + i, "wanmac=", 7)) {
336 memcpy(s, buffer + i + 7, 17);
337 s[17] = 0;
338 nvram_set("et0macaddr", s);
339 found = 1;
343 free(buffer);
344 fclose(fp);
347 return (found);
350 static void check_bootnv(void)
352 int dirty;
353 int hardware;
354 int model;
356 model = get_model();
357 dirty = 0;
359 switch (model) {
360 case MODEL_WTR54GS:
361 dirty |= check_nv("vlan0hwname", "et0");
362 dirty |= check_nv("vlan1hwname", "et0");
363 break;
364 case MODEL_WL500GP:
365 dirty |= check_nv("sdram_init", "0x0009"); // 32MB; defaults: 0x000b, 0x0009
366 if (nvram_match("vlan1ports", "0 5u")) // default: 0 5u
367 dirty |= check_nv("vlan1ports", "0 5");
368 break;
369 case MODEL_WL500W:
370 /* fix WL500W mac adresses for WAN port */
371 if (nvram_match("et1macaddr", "00:90:4c:a1:00:2d"))
372 dirty |= check_nv("et1macaddr", nvram_get("et0macaddr"));
373 break;
374 case MODEL_WL500GE:
375 if (nvram_match("vlan1ports", "0 5u")) // default: 0 5u
376 dirty |= check_nv("vlan1ports", "0 5");
377 break;
378 case MODEL_WL500GPv2:
379 if (nvram_match("vlan1ports", "4 5u"))
380 dirty |= check_nv("vlan1ports", "4 5");
381 else if (nvram_match("vlan1ports", "0 5u")) // 520GU?
382 dirty |= check_nv("vlan1ports", "0 5");
383 break;
384 case MODEL_WL520GU:
385 if (nvram_match("vlan1ports", "0 5u"))
386 dirty |= check_nv("vlan1ports", "0 5");
387 break;
388 case MODEL_WL500GD:
389 dirty |= check_nv("vlan0hwname", "et0");
390 dirty |= check_nv("vlan1hwname", "et0");
391 if (!nvram_get("vlan0ports")) {
392 dirty |= check_nv("vlan0ports", "1 2 3 4 5*");
393 dirty |= check_nv("vlan1ports", "0 5");
395 break;
396 case MODEL_DIR320:
397 if (strlen(nvram_safe_get("et0macaddr")) == 12) {
398 if (!find_dir320_mac_addr()) {
399 // goofy et0macaddr, make something up
400 nvram_set("et0macaddr", "00:90:4c:c0:00:01");
402 dirty = 1;
404 if (nvram_get("vlan2ports") != NULL) {
405 nvram_unset("vlan2ports");
406 nvram_unset("vlan2hwname");
407 dirty = 1;
409 dirty |= check_nv("vlan1hwname", "et0");
410 if ((nvram_get("vlan1ports") == NULL) || nvram_match("vlan1ports", "0 5u"))
411 dirty |= check_nv("vlan1ports", "0 5");
412 break;
413 #ifdef CONFIG_BCMWL5
414 case MODEL_WNR3500L:
415 dirty |= check_nv("boardflags", "0x00000710"); // needed to enable USB
416 dirty |= check_nv("vlan2hwname", "et0");
417 if (nvram_match("vlan1ports", "1 2 3 4 8*") || nvram_match("vlan2ports", "0 8u")) {
418 dirty |= check_nv("vlan1ports", "4 3 2 1 8*");
419 dirty |= check_nv("vlan2ports", "0 8");
421 dirty |= check_nv("ledbh0", "7");
422 break;
423 case MODEL_WNR2000v2:
424 if (nvram_match("vlan0ports", "1 2 3 4 5*") || nvram_match("vlan1ports", "0 5u")) {
425 dirty |= check_nv("vlan0ports", "4 3 2 1 5*");
426 dirty |= check_nv("vlan1ports", "0 5");
428 if (nvram_match("ledbh5", "2"))
429 dirty |= check_nv("ledbh5", "8");
430 break;
431 case MODEL_RTN10:
432 if (nvram_match("vlan1ports", "4 5u"))
433 dirty |= check_nv("vlan1ports", "4 5");
434 break;
435 case MODEL_RTN12:
436 if (nvram_match("vlan0ports", "0 1 2 3 5*") || nvram_match("vlan1ports", "4 5u")) {
437 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
438 dirty |= check_nv("vlan1ports", "4 5");
440 break;
441 case MODEL_WRT320N:
442 dirty |= check_nv("reset_gpio", "5");
443 dirty |= check_nv("ledbh0", "136");
444 dirty |= check_nv("ledbh1", "11");
445 /* fall through, same as RT-N16 */
446 case MODEL_RTN16:
447 dirty |= check_nv("vlan2hwname", "et0");
448 if (nvram_match("vlan1ports", "1 2 3 4 8*") || nvram_match("vlan2ports", "0 8u")) {
449 dirty |= check_nv("vlan1ports", "4 3 2 1 8*");
450 dirty |= check_nv("vlan2ports", "0 8");
452 break;
453 case MODEL_WRT160Nv3:
454 if (nvram_match("clkdivsf", "4") && nvram_match("vlan1ports", "1 2 3 4 5*")) {
455 // fix lan port numbering on CSE41, CSE51
456 dirty |= check_nv("vlan1ports", "4 3 2 1 5*");
458 break;
459 #endif
461 case MODEL_WRT54G:
462 if (strncmp(nvram_safe_get("pmon_ver"), "CFE", 3) != 0) return;
464 hardware = check_hw_type();
465 if (!nvram_get("boardtype") ||
466 !nvram_get("boardnum") ||
467 !nvram_get("boardflags") ||
468 !nvram_get("clkfreq") ||
469 !nvram_get("os_flash_addr") ||
470 !nvram_get("dl_ram_addr") ||
471 !nvram_get("os_ram_addr") ||
472 !nvram_get("scratch") ||
473 !nvram_get("et0macaddr") ||
474 ((hardware != HW_BCM4704_BCM5325F) && (!nvram_get("vlan0ports") || !nvram_get("vlan0hwname")))) {
475 cprintf("Unable to find critical settings, erasing NVRAM\n");
476 mtd_erase("nvram");
477 goto REBOOT;
480 dirty |= check_nv("aa0", "3");
481 dirty |= check_nv("wl0gpio0", "136");
482 dirty |= check_nv("wl0gpio2", "0");
483 dirty |= check_nv("wl0gpio3", "0");
484 dirty |= check_nv("cctl", "0");
485 dirty |= check_nv("ccode", "0");
487 switch (hardware) {
488 case HW_BCM5325E:
489 /* Lower the DDR ram drive strength , the value will be stable for all boards
490 Latency 3 is more stable for all ddr 20050420 by honor */
491 dirty |= check_nv("sdram_init", "0x010b");
492 dirty |= check_nv("sdram_config", "0x0062");
493 if (!nvram_match("debug_clkfix", "0")) {
494 dirty |= check_nv("clkfreq", "216");
496 if (dirty) {
497 nvram_set("sdram_ncdl", "0x0");
499 dirty |= check_nv("pa0itssit", "62");
500 dirty |= check_nv("pa0b0", "0x15eb");
501 dirty |= check_nv("pa0b1", "0xfa82");
502 dirty |= check_nv("pa0b2", "0xfe66");
503 //dirty |= check_nv("pa0maxpwr", "0x4e");
504 break;
505 case HW_BCM5352E: // G v4, GS v3, v4
506 dirty |= check_nv("sdram_init", "0x010b");
507 dirty |= check_nv("sdram_config", "0x0062");
508 if (dirty) {
509 nvram_set("sdram_ncdl", "0x0");
511 dirty |= check_nv("pa0itssit", "62");
512 dirty |= check_nv("pa0b0", "0x168b");
513 dirty |= check_nv("pa0b1", "0xfabf");
514 dirty |= check_nv("pa0b2", "0xfeaf");
515 //dirty |= check_nv("pa0maxpwr", "0x4e");
516 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
517 break;
518 case HW_BCM5354G:
519 dirty |= check_nv("pa0itssit", "62");
520 dirty |= check_nv("pa0b0", "0x1326");
521 dirty |= check_nv("pa0b1", "0xFB51");
522 dirty |= check_nv("pa0b2", "0xFE87");
523 //dirty |= check_nv("pa0maxpwr", "0x4e");
524 break;
525 case HW_BCM4704_BCM5325F:
526 // nothing to do
527 break;
528 default:
529 dirty |= check_nv("pa0itssit", "62");
530 dirty |= check_nv("pa0b0", "0x170c");
531 dirty |= check_nv("pa0b1", "0xfa24");
532 dirty |= check_nv("pa0b2", "0xfe70");
533 //dirty |= check_nv("pa0maxpwr", "0x48");
534 break;
536 break;
538 } // switch (model)
540 if (dirty) {
541 nvram_commit();
542 REBOOT: // do a simple reboot
543 sync();
544 reboot(RB_AUTOBOOT);
545 exit(0);
549 static int init_nvram(void)
551 unsigned long features;
552 int model;
553 const char *mfr;
554 const char *name;
555 char s[256];
556 unsigned long bf;
557 unsigned long n;
559 model = get_model();
560 sprintf(s, "%d", model);
561 nvram_set("t_model", s);
563 mfr = "Broadcom";
564 name = NULL;
565 features = 0;
566 switch (model) {
567 case MODEL_WRT54G:
568 mfr = "Linksys";
569 name = "WRT54G/GS/GL";
570 switch (check_hw_type()) {
571 case HW_BCM4712:
572 nvram_set("gpio2", "adm_eecs");
573 nvram_set("gpio3", "adm_eesk");
574 nvram_unset("gpio4");
575 nvram_set("gpio5", "adm_eedi");
576 nvram_set("gpio6", "adm_rc");
577 break;
578 case HW_BCM4702:
579 nvram_unset("gpio2");
580 nvram_unset("gpio3");
581 nvram_unset("gpio4");
582 nvram_unset("gpio5");
583 nvram_unset("gpio6");
584 break;
585 case HW_BCM5352E:
586 nvram_set("opo", "0x0008");
587 nvram_set("ag0", "0x02");
588 // drop
589 default:
590 nvram_set("gpio2", "ses_led");
591 nvram_set("gpio3", "ses_led2");
592 nvram_set("gpio4", "ses_button");
593 features = SUP_SES | SUP_WHAM_LED;
594 break;
596 break;
597 case MODEL_WTR54GS:
598 mfr = "Linksys";
599 name = "WTR54GS";
600 if (!nvram_match("t_fix1", (char *)name)) {
601 nvram_set("vlan0ports", "0 5*");
602 nvram_set("vlan1ports", "1 5");
603 nvram_set("vlan_enable", "1");
604 nvram_set("lan_ifnames", "vlan0 eth1");
605 nvram_set("gpio2", "ses_button");
606 nvram_set("reset_gpio", "7");
608 nvram_set("pa0itssit", "62");
609 nvram_set("pa0b0", "0x1542");
610 nvram_set("pa0b1", "0xfacb");
611 nvram_set("pa0b2", "0xfec7");
612 //nvram_set("pa0maxpwr", "0x4c");
613 features = SUP_SES;
614 break;
615 case MODEL_WRTSL54GS:
616 mfr = "Linksys";
617 name = "WRTSL54GS";
618 features = SUP_SES | SUP_WHAM_LED;
619 break;
620 case MODEL_WHRG54S:
621 mfr = "Buffalo";
622 name = "WHR-G54S";
623 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
624 break;
625 case MODEL_WHRHPG54:
626 case MODEL_WZRRSG54HP:
627 case MODEL_WZRHPG54:
628 mfr = "Buffalo";
629 features = SUP_SES | SUP_AOSS_LED | SUP_HPAMP;
630 switch (model) {
631 case MODEL_WZRRSG54HP:
632 name = "WZR-RS-G54HP";
633 break;
634 case MODEL_WZRHPG54:
635 name = "WZR-HP-G54";
636 break;
637 default:
638 name = "WHR-HP-G54";
639 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_HPAMP;
640 break;
643 bf = strtoul(nvram_safe_get("boardflags"), NULL, 0);
644 switch (bf) {
645 case 0x0758:
646 case 0x1758:
647 case 0x2758:
648 case 0x3758:
649 if (nvram_match("wlx_hpamp", "")) {
650 if (nvram_get_int("wl_txpwr") > 10) nvram_set("wl_txpwr", "10");
651 nvram_set("wlx_hpamp", "1");
652 nvram_set("wlx_hperx", "0");
655 n = bf;
656 if (nvram_match("wlx_hpamp", "0")) {
657 n &= ~0x2000UL;
659 else {
660 n |= 0x2000UL;
662 if (nvram_match("wlx_hperx", "0")) {
663 n |= 0x1000UL;
665 else {
666 n &= ~0x1000UL;
668 if (bf != n) {
669 sprintf(s, "0x%lX", n);
670 nvram_set("boardflags", s);
672 break;
673 default:
674 syslog(LOG_WARNING, "Unexpected: boardflag=%lX", bf);
675 break;
677 break;
678 case MODEL_WBRG54:
679 mfr = "Buffalo";
680 name = "WBR-G54";
681 nvram_set("wl0gpio0", "130");
682 break;
683 case MODEL_WBR2G54:
684 mfr = "Buffalo";
685 name = "WBR2-G54";
686 features = SUP_SES | SUP_AOSS_LED;
687 break;
688 case MODEL_WHR2A54G54:
689 mfr = "Buffalo";
690 name = "WHR2-A54G54";
691 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
692 break;
693 case MODEL_WHR3AG54:
694 mfr = "Buffalo";
695 name = "WHR3-AG54";
696 features = SUP_SES | SUP_AOSS_LED;
697 break;
698 case MODEL_WZRG54:
699 mfr = "Buffalo";
700 name = "WZR-G54";
701 features = SUP_SES | SUP_AOSS_LED;
702 break;
703 case MODEL_WZRRSG54:
704 mfr = "Buffalo";
705 name = "WZR-RS-G54";
706 features = SUP_SES | SUP_AOSS_LED;
707 break;
708 case MODEL_WVRG54NF:
709 mfr = "Buffalo";
710 name = "WVR-G54-NF";
711 features = SUP_SES;
712 break;
713 case MODEL_WZRG108:
714 mfr = "Buffalo";
715 name = "WZR-G108";
716 features = SUP_SES | SUP_AOSS_LED;
717 break;
718 case MODEL_RT390W:
719 mfr = "Fuji";
720 name = "RT390W";
721 break;
722 case MODEL_WR850GV1:
723 mfr = "Motorola";
724 name = "WR850G v1";
725 features = SUP_NONVE;
726 break;
727 case MODEL_WR850GV2:
728 mfr = "Motorola";
729 name = "WR850G v2/v3";
730 features = SUP_NONVE;
731 break;
732 case MODEL_WL500GP:
733 mfr = "Asus";
734 name = "WL-500gP";
735 features = SUP_SES;
736 if (!nvram_match("t_fix1", (char *)name)) {
737 nvram_set("t_fix1", name);
738 nvram_set("lan_ifnames", "vlan0 eth1 eth2 eth3"); // set to "vlan0 eth2" by DD-WRT; default: vlan0 eth1
739 // !!TB - WLAN LED fix
740 nvram_set("wl0gpio0", "136");
742 break;
743 case MODEL_WL500W:
744 mfr = "Asus";
745 name = "WL-500W";
746 features = SUP_SES | SUP_80211N;
747 /* fix AIR LED */
748 if (!nvram_get("wl0gpio0") || nvram_match("wl0gpio0", "2"))
749 nvram_set("wl0gpio0", "0x88");
750 break;
751 case MODEL_WL500GE:
752 mfr = "Asus";
753 name = "WL-500gE";
754 // features = ?
755 break;
756 case MODEL_WX6615GT:
757 mfr = "SparkLAN";
758 name = "WX-6615GT";
759 // features = ?
760 break;
761 case MODEL_MN700:
762 mfr = "Microsoft";
763 name = "MN-700";
764 break;
765 case MODEL_WR100:
766 mfr = "Viewsonic";
767 name = "WR100";
768 break;
769 case MODEL_WLA2G54L:
770 mfr = "Buffalo";
771 name = "WLA2-G54L";
772 if (!nvram_match("t_fix1", (char *)name)) {
773 nvram_set("t_fix1", name);
774 nvram_set("lan_ifnames", "vlan0 eth1 eth2");
775 nvram_set("wl_ifname", "eth1");
776 nvram_set("wan_ifname", "none");
778 break;
779 case MODEL_TM2300:
780 mfr = "Dell";
781 name = "TrueMobile 2300";
782 break;
790 #ifndef WL_BSS_INFO_VERSION
791 #error WL_BSS_INFO_VERSION
792 #endif
793 #if WL_BSS_INFO_VERSION >= 108
795 case MODEL_WRH54G:
796 mfr = "Linksys";
797 name = "WRH54G";
799 nvram_set("opo", "12");
800 break;
802 case MODEL_WHRG125:
803 mfr = "Buffalo";
804 name = "WHR-G125";
805 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
807 nvram_set("opo", "0x0008");
808 nvram_set("ag0", "0x0C");
809 break;
810 #ifdef CONFIG_BCMWL5
811 case MODEL_RTN10:
812 mfr = "Asus";
813 name = "RT-N10";
814 features = SUP_SES | SUP_80211N;
815 if (!nvram_match("t_fix1", (char *)name)) {
816 nvram_set("lan_ifnames", "vlan0 eth1");
817 nvram_set("wan_ifnameX", "vlan1");
818 nvram_set("wl_ifname", "eth1");
819 nvram_set("t_fix1", name);
821 break;
822 case MODEL_RTN12:
823 mfr = "Asus";
824 name = "RT-N12";
825 features = SUP_SES | SUP_BRAU | SUP_80211N;
826 if (!nvram_match("t_fix1", (char *)name)) {
827 nvram_set("lan_ifnames", "vlan0 eth1");
828 nvram_set("wan_ifnameX", "vlan1");
829 nvram_set("wl_ifname", "eth1");
830 nvram_set("t_fix1", name);
832 break;
833 case MODEL_RTN16:
834 mfr = "Asus";
835 name = "RT-N16";
836 features = SUP_SES | SUP_80211N | SUP_1000ET;
837 if (!nvram_match("t_fix1", (char *)name)) {
838 nvram_set("lan_ifnames", "vlan1 eth1");
839 nvram_set("wan_ifnameX", "vlan2");
840 nvram_set("wl_ifname", "eth1");
841 nvram_set("vlan_enable", "1");
842 nvram_set("t_fix1", name);
844 break;
845 case MODEL_WNR3500L:
846 mfr = "Netgear";
847 name = "WNR3500L/U/v2";
848 features = SUP_SES | SUP_AOSS_LED | SUP_80211N | SUP_1000ET;
849 if (!nvram_match("t_fix1", (char *)name)) {
850 nvram_set("sromrev", "3");
851 nvram_set("lan_ifnames", "vlan1 eth1");
852 nvram_set("wan_ifnameX", "vlan2");
853 nvram_set("wl_ifname", "eth1");
854 nvram_set("portprio_support", "0");
855 nvram_set("t_fix1", name);
857 break;
858 case MODEL_WNR2000v2:
859 mfr = "Netgear";
860 name = "WNR2000 v2";
861 features = SUP_SES | SUP_AOSS_LED | SUP_80211N;
862 if (!nvram_match("t_fix1", (char *)name)) {
863 nvram_set("lan_ifnames", "vlan0 eth1");
864 nvram_set("wan_ifnameX", "vlan1");
865 nvram_set("wl_ifname", "eth1");
866 nvram_set("t_fix1", name);
868 break;
869 case MODEL_WRT160Nv3:
870 mfr = "Linksys";
871 if (nvram_match("boot_hw_model", "M10") && nvram_match("boot_hw_ver", "1.0"))
872 name = "M10 v1"; // renamed wrt160nv3
873 else
874 name = "WRT160N v3";
875 features = SUP_SES | SUP_80211N | SUP_WHAM_LED;
876 if (!nvram_match("t_fix1", (char *)name)) {
877 nvram_set("lan_ifnames", "vlan1 eth1");
878 nvram_set("wan_ifnameX", "vlan2");
879 nvram_set("wl_ifname", "eth1");
880 nvram_set("t_fix1", name);
882 break;
883 case MODEL_WRT320N:
884 mfr = "Linksys";
885 if (nvram_match("boardrev", "0x1307")) {
886 name = "E2000";
887 gpio_write(1 << 0, 0); // fix for WLAN LED
888 } else
889 name = "WRT320N";
890 features = SUP_SES | SUP_80211N | SUP_WHAM_LED | SUP_1000ET;
891 if (!nvram_match("t_fix1", (char *)name)) {
892 nvram_set("lan_ifnames", "vlan1 eth1");
893 nvram_set("wan_ifnameX", "vlan2");
894 nvram_set("wl_ifname", "eth1");
895 nvram_set("t_fix1", name);
897 break;
898 #endif // CONFIG_BCMWL5
899 case MODEL_WL500GPv2:
900 mfr = "Asus";
901 name = "WL-500gP v2";
902 features = SUP_SES;
903 if (!nvram_match("t_fix1", (char *)name)) {
904 nvram_set("t_fix1", name);
906 /* fix AIR LED */
907 if (nvram_match("wl0gpio1", "0x02"))
908 nvram_set("wl0gpio1", "0x88");
909 break;
910 case MODEL_WL520GU:
911 mfr = "Asus";
912 name = "WL-520GU";
913 features = SUP_SES;
914 if (!nvram_match("t_fix1", (char *)name)) {
915 nvram_set("t_fix1", name);
916 // !!TB - LED fix
917 nvram_set("wl0gpio0", "0");
918 nvram_set("wl0gpio1", "136");
919 nvram_set("wl0gpio2", "0");
920 nvram_set("wl0gpio3", "0");
922 break;
923 case MODEL_WL500GD:
924 mfr = "Asus";
925 name = "WL-500g Deluxe";
926 // features = SUP_SES;
927 if (!nvram_match("t_fix1", (char *)name)) {
928 nvram_set("t_fix1", name);
929 nvram_set("wl_ifname", "eth1");
930 nvram_set("lan_ifnames", "vlan0 eth1");
931 nvram_set("wan_ifnameX", "vlan1");
932 nvram_unset("wl0gpio0");
934 break;
935 case MODEL_DIR320:
936 mfr = "D-Link";
937 name = "DIR-320";
938 features = SUP_SES;
939 if (!nvram_match("t_fix1", (char *)name)) {
940 nvram_set("t_fix1", name);
941 nvram_set("lan_ifnames", "vlan0 eth1 eth2 eth3");
942 nvram_set("wan_ifnameX", "vlan1");
943 nvram_set("wl_ifname", "eth1");
944 nvram_set("wl0gpio0", "8");
945 nvram_set("wl0gpio1", "0");
946 nvram_set("wl0gpio2", "0");
947 nvram_set("wl0gpio3", "0");
949 break;
950 #endif // WL_BSS_INFO_VERSION >= 108
951 #if TOMATO_N
952 case MODEL_WZRG300N:
953 mfr = "Buffalo";
954 name = "WZR-G300N";
955 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_80211N;
956 break;
957 case MODEL_WRT300N:
958 mfr = "Linksys";
959 name = "WRT300N v1";
960 features = SUP_SES | SUP_80211N;
961 if (!nvram_match("t_fix1", (char *)name)) {
962 nvram_set("wan_ifnameX", "eth1");
963 nvram_set("wl0gpio0", "8");
965 break;
966 #endif
969 if (name) {
970 sprintf(s, "%s %s", mfr, name);
972 else {
973 snprintf(s, sizeof(s), "%s %d/%s/%s/%s/%s", mfr, check_hw_type(),
974 nvram_safe_get("boardtype"), nvram_safe_get("boardnum"), nvram_safe_get("boardrev"), nvram_safe_get("boardflags"));
975 s[64] = 0;
977 nvram_set("t_model_name", s);
979 nvram_set("pa0maxpwr", "251"); // allow Tx power up tp 251 mW, needed for ND only
981 sprintf(s, "0x%lX", features);
982 nvram_set("t_features", s);
987 note: set wan_ifnameX if wan_ifname needs to be overriden
990 if (nvram_is_empty("wan_ifnameX")) {
991 #if 1
992 nvram_set("wan_ifnameX", ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
993 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1");
994 #else
995 p = nvram_safe_get("wan_ifname");
996 if ((*p == 0) || (nvram_match("wl_ifname", p))) {
997 p = ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
998 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
1000 nvram_set("wan_ifnameX", p);
1001 #endif
1005 nvram_set("wl_hwaddr", ""); // when disabling wireless, we must get null wireless mac ??
1006 //!!TB - do not force country code here to allow nvram override
1007 //nvram_set("wl_country", "JP");
1008 //nvram_set("wl_country_code", "JP");
1009 nvram_set("wan_get_dns", "");
1010 nvram_set("wan_get_domain", "");
1011 nvram_set("pppoe_pid0", "");
1012 nvram_set("action_service", "");
1013 nvram_set("jffs2_format", "0");
1014 nvram_set("rrules_radio", "-1");
1015 nvram_unset("https_crt_gen");
1016 #ifdef TCONFIG_MEDIA_SERVER
1017 nvram_unset("ms_rescan");
1018 #endif
1019 if (nvram_get_int("http_id_gen") == 1) nvram_unset("http_id");
1021 nvram_unset("sch_rboot_last");
1022 nvram_unset("sch_rcon_last");
1023 nvram_unset("sch_c1_last");
1024 nvram_unset("sch_c2_last");
1025 nvram_unset("sch_c3_last");
1027 nvram_set("brau_state", "");
1028 if ((features & SUP_BRAU) == 0) nvram_set("script_brau", "");
1029 if ((features & SUP_SES) == 0) nvram_set("sesx_script", "");
1031 if ((features & SUP_1000ET) == 0) nvram_set("jumbo_frame_enable", "0");
1033 if (nvram_match("wl_net_mode", "disabled")) {
1034 nvram_set("wl_radio", "0");
1035 nvram_set("wl_net_mode", "mixed");
1038 return 0;
1041 /* Get the special files from nvram and copy them to disc.
1042 * These were files saved with "nvram setfile2nvram <filename>".
1043 * Better hope that they were saved with full pathname.
1045 static void load_files_from_nvram(void)
1047 char *name, *cp;
1048 char buf[NVRAM_SPACE];
1050 if (nvram_getall(buf, sizeof(buf)) != 0)
1051 return;
1053 for (name = buf; *name; name += strlen(name) + 1) {
1054 if (strncmp(name, "FILE:", 5) == 0) { /* This special name marks a file to get. */
1055 if ((cp = strchr(name, '=')) == NULL)
1056 continue;
1057 *cp = 0;
1058 syslog(LOG_INFO, "Loading file '%s' from nvram", name + 5);
1059 nvram_nvram2file(name, name + 5);
1064 #if defined(LINUX26) && defined(TCONFIG_USB)
1065 static inline void tune_min_free_kbytes(void)
1067 struct sysinfo info;
1069 memset(&info, 0, sizeof(struct sysinfo));
1070 sysinfo(&info);
1071 if (info.totalram >= 55 * 1024 * 1024) {
1072 // If we have 64MB+ RAM, tune min_free_kbytes
1073 // to reduce page allocation failure errors.
1074 f_write_string("/proc/sys/vm/min_free_kbytes", "8192", 0, 0);
1077 #endif
1079 static void sysinit(void)
1081 static const time_t tm = 0;
1082 int hardware;
1083 int i;
1084 DIR *d;
1085 struct dirent *de;
1086 char s[256];
1087 char t[256];
1088 int model;
1090 mount("proc", "/proc", "proc", 0, NULL);
1091 mount("tmpfs", "/tmp", "tmpfs", 0, NULL);
1093 #ifdef LINUX26
1094 mount("devfs", "/dev", "tmpfs", MS_MGC_VAL | MS_NOATIME, NULL);
1095 mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3));
1096 mknod("/dev/console", S_IFCHR | 0600, makedev(5, 1));
1097 mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL);
1098 mkdir("/dev/shm", 0777);
1099 mkdir("/dev/pts", 0777);
1100 mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, NULL);
1101 #endif
1103 if (console_init()) noconsole = 1;
1105 stime(&tm);
1107 static const char *mkd[] = {
1108 "/tmp/etc", "/tmp/var", "/tmp/home", "/tmp/mnt",
1109 "/tmp/share", "/var/webmon", // !!TB
1110 "/var/log", "/var/run", "/var/tmp", "/var/lib", "/var/lib/misc",
1111 "/var/spool", "/var/spool/cron", "/var/spool/cron/crontabs",
1112 "/tmp/var/wwwext", "/tmp/var/wwwext/cgi-bin", // !!TB - CGI support
1113 NULL
1115 umask(0);
1116 for (i = 0; mkd[i]; ++i) {
1117 mkdir(mkd[i], 0755);
1119 mkdir("/var/lock", 0777);
1120 mkdir("/var/tmp/dhcp", 0777);
1121 mkdir("/home/root", 0700);
1122 chmod("/tmp", 0777);
1123 f_write("/etc/hosts", NULL, 0, 0, 0644); // blank
1124 f_write("/etc/fstab", NULL, 0, 0, 0644); // !!TB - blank
1125 simple_unlock("cron");
1126 simple_unlock("firewall");
1127 simple_unlock("restrictions");
1128 umask(022);
1130 if ((d = opendir("/rom/etc")) != NULL) {
1131 while ((de = readdir(d)) != NULL) {
1132 if (de->d_name[0] == '.') continue;
1133 snprintf(s, sizeof(s), "%s/%s", "/rom/etc", de->d_name);
1134 snprintf(t, sizeof(t), "%s/%s", "/etc", de->d_name);
1135 symlink(s, t);
1137 closedir(d);
1139 symlink("/proc/mounts", "/etc/mtab");
1141 #ifdef TCONFIG_SAMBASRV
1142 if ((d = opendir("/usr/codepages")) != NULL) {
1143 while ((de = readdir(d)) != NULL) {
1144 if (de->d_name[0] == '.') continue;
1145 snprintf(s, sizeof(s), "/usr/codepages/%s", de->d_name);
1146 snprintf(t, sizeof(t), "/usr/share/%s", de->d_name);
1147 symlink(s, t);
1149 closedir(d);
1151 #endif
1153 #ifdef LINUX26
1154 eval("hotplug2", "--coldplug");
1155 start_hotplug2();
1156 #endif
1158 set_action(ACT_IDLE);
1160 for (i = 0; defenv[i]; ++i) {
1161 putenv(defenv[i]);
1164 if (!noconsole) {
1165 printf("\n\nHit ENTER for console...\n\n");
1166 run_shell(1, 0);
1169 check_bootnv();
1171 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++) {
1172 signal(fatalsigs[i], handle_fatalsigs);
1174 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++) {
1175 signal(initsigs[i], handle_initsigs);
1177 signal(SIGCHLD, handle_reap);
1179 switch (model = get_model()) {
1180 case MODEL_WR850GV1:
1181 case MODEL_WR850GV2:
1182 // need to cleanup some variables...
1183 if ((nvram_get("t_model") == NULL) && (nvram_get("MyFirmwareVersion") != NULL)) {
1184 nvram_unset("MyFirmwareVersion");
1185 nvram_set("restore_defaults", "1");
1187 break;
1190 #ifdef CONFIG_BCMWL5
1191 // ctf must be loaded prior to any other modules
1192 modprobe("ctf");
1193 #endif
1195 hardware = check_hw_type();
1196 #if WL_BSS_INFO_VERSION >= 108
1197 modprobe("et");
1198 #else
1199 if ((hardware == HW_BCM4702) && (model != MODEL_WR850GV1)) {
1200 modprobe("4702et");
1201 modprobe("diag");
1203 else {
1204 modprobe("et");
1206 #endif
1208 #ifdef CONFIG_BCMWL5
1209 modprobe("emf");
1210 modprobe("igs");
1211 #endif
1212 modprobe("wl");
1213 modprobe("tomato_ct");
1215 config_loopback();
1217 system("nvram defaults --initcheck");
1218 init_nvram();
1220 // set the packet size
1221 if (nvram_get_int("jumbo_frame_enable")) {
1222 // only set the size here - 'enable' flag is set by the driver
1223 // eval("et", "robowr", "0x40", "0x01", "0x1F"); // (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)
1224 eval("et", "robowr", "0x40", "0x05", nvram_safe_get("jumbo_frame_size"));
1227 klogctl(8, NULL, nvram_get_int("console_loglevel"));
1229 #if defined(LINUX26) && defined(TCONFIG_USB)
1230 tune_min_free_kbytes();
1231 #endif
1232 setup_conntrack();
1233 set_host_domain_name();
1235 start_jffs2();
1237 set_tz();
1239 eval("buttons");
1241 i = nvram_get_int("sesx_led");
1242 led(LED_AMBER, (i & 1) != 0);
1243 led(LED_WHITE, (i & 2) != 0);
1244 led(LED_AOSS, (i & 4) != 0);
1245 led(LED_BRIDGE, (i & 8) != 0);
1246 led(LED_DIAG, 1);
1249 int init_main(int argc, char *argv[])
1251 pid_t shell_pid = 0;
1253 sysinit();
1255 state = START;
1256 signaled = -1;
1258 #if defined(DEBUG_NOISY)
1259 nvram_set("debug_logeval", "1");
1260 nvram_set("debug_cprintf", "1");
1261 nvram_set("debug_cprintf_file", "1");
1262 nvram_set("debug_ddns", "1");
1263 #endif
1265 for (;;) {
1266 // TRACE_PT("main loop state=%d\n", state);
1268 switch (state) {
1269 case USER1:
1270 exec_service();
1271 state = IDLE;
1272 break;
1273 case RESTART:
1274 case STOP:
1275 case HALT:
1276 case REBOOT:
1277 led(LED_DIAG, 1);
1278 unlink("/var/notice/sysup");
1280 run_nvscript("script_shut", NULL, 10);
1282 stop_services();
1283 stop_wan();
1284 stop_lan();
1285 stop_vlan();
1286 stop_syslog();
1288 if ((state == REBOOT) || (state == HALT)) {
1289 remove_storage_main(1);
1290 stop_usb();
1292 shutdn(state == REBOOT);
1293 exit(0);
1295 if (state == STOP) {
1296 state = IDLE;
1297 break;
1300 // RESTART falls through
1302 case START:
1303 SET_LED(RELEASE_WAN_CONTROL);
1304 start_syslog();
1306 load_files_from_nvram();
1308 int fd = -1;
1309 fd = file_lock("usb"); // hold off automount processing
1310 start_usb();
1312 run_nvscript("script_init", NULL, 2);
1314 file_unlock(fd); // allow to process usb hotplug events
1315 #ifdef TCONFIG_USB
1317 * On RESTART some partitions can stay mounted if they are busy at the moment.
1318 * In that case USB drivers won't unload, and hotplug won't kick off again to
1319 * remount those drives that actually got unmounted. Make sure to remount ALL
1320 * partitions here by simulating hotplug event.
1322 if (state == RESTART) add_remove_usbhost("-1", 1);
1323 #endif
1325 start_vlan();
1326 start_lan();
1327 start_wan(BOOT);
1328 start_services();
1329 start_wl();
1331 #ifdef CONFIG_BCMWL5
1332 if (nvram_match("wds_enable", "1")) {
1333 /* Restart NAS one more time - for some reason without
1334 * this the new driver doesn't always bring WDS up.
1336 stop_nas();
1337 start_nas();
1339 #endif
1341 syslog(LOG_INFO, "Tomato %s", tomato_version);
1342 syslog(LOG_INFO, "%s", nvram_safe_get("t_model_name"));
1344 led(LED_DIAG, 0);
1345 notice_set("sysup", "");
1347 state = IDLE;
1349 // fall through
1351 case IDLE:
1352 while (signaled == -1) {
1353 check_services();
1354 if ((!noconsole) && ((!shell_pid) || (kill(shell_pid, 0) != 0))) {
1355 shell_pid = run_shell(0, 1);
1357 else {
1358 pause();
1361 state = signaled;
1362 signaled = -1;
1363 break;
1368 int reboothalt_main(int argc, char *argv[])
1370 int reboot = (strstr(argv[0], "reboot") != NULL);
1371 puts(reboot ? "Rebooting..." : "Shutting down...");
1372 fflush(stdout);
1373 sleep(1);
1374 kill(1, reboot ? SIGTERM : SIGQUIT);
1376 /* In the case we're hung, we'll get stuck and never actually reboot.
1377 * The only way out is to pull power.
1378 * So after 10 seconds, forcibly crash & restart.
1380 if (fork() == 0) {
1381 int wait = nvram_get_int("reset_wait");
1382 if ((wait < 10) || (wait > 120)) wait = 10;
1384 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1385 sleep(wait);
1386 puts("Still running... Doing machine reset.");
1387 fflush(stdout);
1388 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1389 sleep(1);
1390 f_write("/proc/sysrq-trigger", "b", 1, 0 , 0); /* machine reset */
1393 return 0;