ipv6: add DHCPv6 with Prefix Delegation support (based on the patch by Paul Donovan)
[tomato.git] / release / src / router / rc / init.c
blob94714a03962fa19b9f0c21dc612d38252d94f329
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"
35 static int fatalsigs[] = {
36 SIGILL,
37 SIGABRT,
38 SIGFPE,
39 SIGPIPE,
40 SIGBUS,
41 SIGSYS,
42 SIGTRAP,
43 SIGPWR
46 static int initsigs[] = {
47 SIGHUP,
48 SIGUSR1,
49 SIGUSR2,
50 SIGINT,
51 SIGQUIT,
52 SIGALRM,
53 SIGTERM
56 static char *defenv[] = {
57 "TERM=vt100",
58 "HOME=/",
59 "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
60 "SHELL=" SHELL,
61 "USER=root",
62 NULL
65 /* Set terminal settings to reasonable defaults */
66 static void set_term(int fd)
68 struct termios tty;
70 tcgetattr(fd, &tty);
72 /* set control chars */
73 tty.c_cc[VINTR] = 3; /* C-c */
74 tty.c_cc[VQUIT] = 28; /* C-\ */
75 tty.c_cc[VERASE] = 127; /* C-? */
76 tty.c_cc[VKILL] = 21; /* C-u */
77 tty.c_cc[VEOF] = 4; /* C-d */
78 tty.c_cc[VSTART] = 17; /* C-q */
79 tty.c_cc[VSTOP] = 19; /* C-s */
80 tty.c_cc[VSUSP] = 26; /* C-z */
82 /* use line dicipline 0 */
83 tty.c_line = 0;
85 /* Make it be sane */
86 tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
87 tty.c_cflag |= CREAD|HUPCL|CLOCAL;
90 /* input modes */
91 tty.c_iflag = ICRNL | IXON | IXOFF;
93 /* output modes */
94 tty.c_oflag = OPOST | ONLCR;
96 /* local modes */
97 tty.c_lflag =
98 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
100 tcsetattr(fd, TCSANOW, &tty);
103 static int console_init(void)
105 int fd;
107 /* Clean up */
108 ioctl(0, TIOCNOTTY, 0);
109 close(0);
110 close(1);
111 close(2);
112 setsid();
114 /* Reopen console */
115 if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) {
116 /* Avoid debug messages is redirected to socket packet if no exist a UART chip, added by honor, 2003-12-04 */
117 open("/dev/null", O_RDONLY);
118 open("/dev/null", O_WRONLY);
119 open("/dev/null", O_WRONLY);
120 perror(_PATH_CONSOLE);
121 return errno;
123 dup2(fd, 0);
124 dup2(fd, 1);
125 dup2(fd, 2);
127 ioctl(0, TIOCSCTTY, 1);
128 tcsetpgrp(0, getpgrp());
129 set_term(0);
131 return 0;
135 * Waits for a file descriptor to change status or unblocked signal
136 * @param fd file descriptor
137 * @param timeout seconds to wait before timing out or 0 for no timeout
138 * @return 1 if descriptor changed status or 0 if timed out or -1 on error
140 static int waitfor(int fd, int timeout)
142 fd_set rfds;
143 struct timeval tv = { timeout, 0 };
145 FD_ZERO(&rfds);
146 FD_SET(fd, &rfds);
147 return select(fd + 1, &rfds, NULL, NULL, (timeout > 0) ? &tv : NULL);
150 static pid_t run_shell(int timeout, int nowait)
152 pid_t pid;
153 int sig;
155 /* Wait for user input */
156 if (waitfor(STDIN_FILENO, timeout) <= 0) return 0;
158 switch (pid = fork()) {
159 case -1:
160 perror("fork");
161 return 0;
162 case 0:
163 /* Reset signal handlers set for parent process */
164 for (sig = 0; sig < (_NSIG-1); sig++)
165 signal(sig, SIG_DFL);
167 /* Reopen console */
168 console_init();
169 printf("\n\nTomato %s\n\n", tomato_version);
171 /* Now run it. The new program will take over this PID,
172 * so nothing further in init.c should be run. */
173 execve(SHELL, (char *[]) { SHELL, NULL }, defenv);
175 /* We're still here? Some error happened. */
176 perror(SHELL);
177 exit(errno);
178 default:
179 if (nowait) {
180 return pid;
182 else {
183 waitpid(pid, NULL, 0);
184 return 0;
189 int console_main(int argc, char *argv[])
191 for (;;) run_shell(0, 0);
193 return 0;
196 static void shutdn(int rb)
198 int i;
199 int act;
200 sigset_t ss;
202 _dprintf("shutdn rb=%d\n", rb);
204 sigemptyset(&ss);
205 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++)
206 sigaddset(&ss, fatalsigs[i]);
207 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++)
208 sigaddset(&ss, initsigs[i]);
209 sigprocmask(SIG_BLOCK, &ss, NULL);
211 for (i = 30; i > 0; --i) {
212 if (((act = check_action()) == ACT_IDLE) || (act == ACT_REBOOT)) break;
213 _dprintf("Busy with %d. Waiting before shutdown... %d\n", act, i);
214 sleep(1);
216 set_action(ACT_REBOOT);
218 // Disconnect pppd - need this for PPTP/L2TP to finish gracefully
219 stop_pptp();
220 stop_l2tp();
222 _dprintf("TERM\n");
223 kill(-1, SIGTERM);
224 sleep(3);
225 sync();
227 _dprintf("KILL\n");
228 kill(-1, SIGKILL);
229 sleep(1);
230 sync();
232 umount("/jffs"); // may hang if not
233 sleep(1);
235 if (rb != -1) {
236 led(LED_WLAN, 0);
237 if (rb == 0) {
238 for (i = 4; i > 0; --i) {
239 led(LED_DMZ, 1);
240 led(LED_WHITE, 1);
241 usleep(250000);
242 led(LED_DMZ, 0);
243 led(LED_WHITE, 0);
244 usleep(250000);
249 reboot(rb ? RB_AUTOBOOT : RB_HALT_SYSTEM);
251 do {
252 sleep(1);
253 } while (1);
256 static void handle_fatalsigs(int sig)
258 _dprintf("fatal sig=%d\n", sig);
259 shutdn(-1);
262 /* Fixed the race condition & incorrect code by using sigwait()
263 * instead of pause(). But SIGCHLD is a problem, since other
264 * code: 1) messes with it and 2) depends on CHLD being caught so
265 * that the pid gets immediately reaped instead of left a zombie.
266 * Pidof still shows the pid, even though it's in zombie state.
267 * So this SIGCHLD handler reaps and then signals the mainline by
268 * raising ALRM.
270 static void handle_reap(int sig)
272 chld_reap(sig);
273 raise(SIGALRM);
276 static int check_nv(const char *name, const char *value)
278 const char *p;
279 if (!nvram_match("manual_boot_nv", "1")) {
280 if (((p = nvram_get(name)) == NULL) || (strcmp(p, value) != 0)) {
281 _dprintf("Error: Critical variable %s is invalid. Resetting.\n", name);
282 nvram_set(name, value);
283 return 1;
286 return 0;
289 static int find_sercom_mac_addr(void)
291 FILE *fp;
292 unsigned char m[6], s[18];
294 sprintf(s, MTD_DEV(%dro), 0);
295 if ((fp = fopen(s, "rb"))) {
296 fseek(fp, 0x1ffa0, SEEK_SET);
297 fread(m, sizeof(m), 1, fp);
298 fclose(fp);
299 sprintf(s, "%02X:%02X:%02X:%02X:%02X:%02X",
300 m[0], m[1], m[2], m[3], m[4], m[5]);
301 nvram_set("et0macaddr", s);
302 return (strncasecmp(s, "00:90:4c", 8) != 0);
304 return 0;
307 static int find_dir320_mac_addr(void)
309 FILE *fp;
310 char *buffer, s[18];
311 int i, part, size, found = 0;
313 if (!mtd_getinfo("board_data", &part, &size))
314 goto out;
315 sprintf(s, MTD_DEV(%dro), part);
317 if ((fp = fopen(s, "rb"))) {
318 buffer = malloc(size);
319 memset(buffer, 0, size);
320 fread(buffer, size, 1, fp);
321 if (!memcmp(buffer, "RGCFG1", 6)) {
322 for (i = 6; i < size - 24; i++) {
323 if (!memcmp(buffer + i, "lanmac=", 7)) {
324 memcpy(s, buffer + i + 7, 17);
325 s[17] = 0;
326 nvram_set("et0macaddr", s);
327 found = 1;
329 else if (!memcmp(buffer + i, "wanmac=", 7)) {
330 memcpy(s, buffer + i + 7, 17);
331 s[17] = 0;
332 nvram_set("il0macaddr", s);
333 if (!found) {
334 inc_mac(s, -1);
335 nvram_set("et0macaddr", s);
337 found = 1;
341 free(buffer);
342 fclose(fp);
344 out:
345 if (!found) {
346 strcpy(s, nvram_safe_get("wl0_hwaddr"));
347 inc_mac(s, -2);
348 nvram_set("et0macaddr", s);
350 return 1;
353 static int init_vlan_ports(void)
355 int dirty = 0;
356 int model = get_model();
358 switch (model) {
359 case MODEL_WRT54G:
360 switch (check_hw_type()) {
361 case HW_BCM5352E: // G v4, GS v3, v4
362 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
363 break;
365 break;
366 case MODEL_WTR54GS:
367 dirty |= check_nv("vlan0ports", "0 5*");
368 dirty |= check_nv("vlan1ports", "1 5");
369 dirty |= check_nv("vlan_enable", "1");
370 break;
371 case MODEL_WL500GP:
372 case MODEL_WL500GE:
373 case MODEL_WL500GPv2:
374 case MODEL_WL520GU:
375 if (nvram_match("vlan1ports", "0 5u")) // 520GU or WL500GE?
376 dirty |= check_nv("vlan1ports", "0 5");
377 else if (nvram_match("vlan1ports", "4 5u"))
378 dirty |= check_nv("vlan1ports", "4 5");
379 break;
380 case MODEL_WL500GD:
381 dirty |= check_nv("vlan0ports", "1 2 3 4 5*");
382 dirty |= check_nv("vlan1ports", "0 5");
383 break;
384 case MODEL_DIR320:
385 case MODEL_H618B:
386 dirty |= (nvram_get("vlan2ports") != NULL);
387 nvram_unset("vlan2ports");
388 dirty |= check_nv("vlan1ports", "0 5");
389 break;
390 case MODEL_WRT310Nv1:
391 dirty |= check_nv("vlan1ports", "1 2 3 4 8*");
392 dirty |= check_nv("vlan2ports", "0 8");
393 break;
394 case MODEL_WL1600GL:
395 dirty |= check_nv("vlan0ports", "0 1 2 3 5*");
396 dirty |= check_nv("vlan1ports", "4 5");
397 break;
398 #ifdef CONFIG_BCMWL5
399 case MODEL_WNR3500L:
400 case MODEL_WRT320N:
401 case MODEL_RTN16:
402 dirty |= check_nv("vlan1ports", "4 3 2 1 8*");
403 dirty |= check_nv("vlan2ports", "0 8");
404 break;
405 case MODEL_WNR2000v2:
406 dirty |= check_nv("vlan0ports", "4 3 2 1 5*");
407 dirty |= check_nv("vlan1ports", "0 5");
408 break;
409 case MODEL_RTN10:
410 dirty |= check_nv("vlan1ports", "4 5");
411 break;
412 case MODEL_RTN12:
413 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
414 dirty |= check_nv("vlan1ports", "4 5");
415 break;
416 case MODEL_WRT610Nv2:
417 dirty |= check_nv("vlan1ports", "1 2 3 4 8*");
418 dirty |= check_nv("vlan2ports", "0 8");
419 break;
420 case MODEL_WRT160Nv3:
421 if (nvram_match("vlan1ports", "1 2 3 4 5*")) {
422 // fix lan port numbering on CSE41, CSE51
423 dirty |= check_nv("vlan1ports", "4 3 2 1 5*");
425 else if (nvram_match("vlan1ports", "1 2 3 4 8*")) {
426 // WRT310Nv2 ?
427 dirty |= check_nv("vlan1ports", "4 3 2 1 8*");
429 break;
430 #endif
433 return dirty;
436 static void check_bootnv(void)
438 int dirty;
439 int hardware;
440 int model;
441 char mac[18];
443 model = get_model();
444 dirty = 0;
446 switch (model) {
447 case MODEL_WTR54GS:
448 dirty |= check_nv("vlan0hwname", "et0");
449 dirty |= check_nv("vlan1hwname", "et0");
450 break;
451 case MODEL_WBRG54:
452 dirty |= check_nv("wl0gpio0", "130");
453 break;
454 case MODEL_WL500W:
455 /* fix WL500W mac adresses for WAN port */
456 if (strncasecmp(nvram_safe_get("et1macaddr"), "00:90:4c", 8) == 0) {
457 strcpy(mac, nvram_safe_get("et0macaddr"));
458 inc_mac(mac, 1);
459 dirty |= check_nv("et1macaddr", mac);
461 dirty |= check_nv("wl0gpio0", "0x88");
462 break;
463 case MODEL_WL500GP:
464 dirty |= check_nv("sdram_init", "0x0009"); // 32MB; defaults: 0x000b, 0x0009
465 dirty |= check_nv("wl0gpio0", "136");
466 break;
467 case MODEL_WL500GPv2:
468 case MODEL_WL520GU:
469 dirty |= check_nv("wl0gpio1", "136");
470 break;
471 case MODEL_WL500GD:
472 dirty |= check_nv("vlan0hwname", "et0");
473 dirty |= check_nv("vlan1hwname", "et0");
474 dirty |= check_nv("boardflags", "0x00000100"); // set BFL_ENETVLAN
475 nvram_unset("wl0gpio0");
476 break;
477 case MODEL_DIR320:
478 if (strlen(nvram_safe_get("et0macaddr")) == 12 ||
479 strlen(nvram_safe_get("il0macaddr")) == 12) {
480 dirty |= find_dir320_mac_addr();
482 if (nvram_get("vlan2hwname") != NULL) {
483 nvram_unset("vlan2hwname");
484 dirty = 1;
486 dirty |= check_nv("wandevs", "vlan1");
487 dirty |= check_nv("vlan1hwname", "et0");
488 dirty |= check_nv("wl0gpio0", "8");
489 dirty |= check_nv("wl0gpio1", "0");
490 dirty |= check_nv("wl0gpio2", "0");
491 dirty |= check_nv("wl0gpio3", "0");
492 case MODEL_WL1600GL:
493 if (strncasecmp(nvram_safe_get("et0macaddr"), "00:90:4c", 8) == 0) {
494 dirty |= find_sercom_mac_addr();
496 break;
497 case MODEL_WRT160Nv1:
498 case MODEL_WRT310Nv1:
499 case MODEL_WRT300N:
500 dirty |= check_nv("wl0gpio0", "8");
501 break;
502 #ifdef CONFIG_BCMWL5
503 case MODEL_WNR3500L:
504 dirty |= check_nv("boardflags", "0x00000710"); // needed to enable USB
505 dirty |= check_nv("vlan2hwname", "et0");
506 dirty |= check_nv("ledbh0", "7");
507 break;
508 case MODEL_WNR2000v2:
509 dirty |= check_nv("ledbh5", "8");
510 break;
511 case MODEL_WRT320N:
512 dirty |= check_nv("reset_gpio", "5");
513 dirty |= check_nv("ledbh0", "136");
514 dirty |= check_nv("ledbh1", "11");
515 /* fall through, same as RT-N16 */
516 case MODEL_RTN16:
517 dirty |= check_nv("vlan2hwname", "et0");
518 break;
519 case MODEL_WRT610Nv2:
520 dirty |= check_nv("vlan2hwname", "et0");
521 dirty |= check_nv("wl1_leddc", "0x640000");
522 dirty |= check_nv("pci/1/1/ledbh2", "8");
523 dirty |= check_nv("sb/1/ledbh1", "8");
524 if (strncasecmp(nvram_safe_get("pci/1/1/macaddr"), "00:90:4c", 8) == 0) {
525 strcpy(mac, nvram_safe_get("et0macaddr"));
526 inc_mac(mac, 3);
527 dirty |= check_nv("pci/1/1/macaddr", mac);
529 break;
530 case MODEL_WRT160Nv3:
531 dirty |= check_nv("vlan2hwname", "et0");
532 break;
533 #endif
535 case MODEL_WRT54G:
536 if (strncmp(nvram_safe_get("pmon_ver"), "CFE", 3) != 0) return;
538 hardware = check_hw_type();
539 if (!nvram_get("boardtype") ||
540 !nvram_get("boardnum") ||
541 !nvram_get("boardflags") ||
542 !nvram_get("clkfreq") ||
543 !nvram_get("os_flash_addr") ||
544 !nvram_get("dl_ram_addr") ||
545 !nvram_get("os_ram_addr") ||
546 !nvram_get("scratch") ||
547 !nvram_get("et0macaddr") ||
548 ((hardware != HW_BCM4704_BCM5325F) && (!nvram_get("vlan0ports") || !nvram_get("vlan0hwname")))) {
549 _dprintf("Unable to find critical settings, erasing NVRAM\n");
550 mtd_erase("nvram");
551 goto REBOOT;
554 dirty |= check_nv("aa0", "3");
555 dirty |= check_nv("wl0gpio0", "136");
556 dirty |= check_nv("wl0gpio2", "0");
557 dirty |= check_nv("wl0gpio3", "0");
558 dirty |= check_nv("cctl", "0");
559 dirty |= check_nv("ccode", "0");
561 switch (hardware) {
562 case HW_BCM5325E:
563 /* Lower the DDR ram drive strength , the value will be stable for all boards
564 Latency 3 is more stable for all ddr 20050420 by honor */
565 dirty |= check_nv("sdram_init", "0x010b");
566 dirty |= check_nv("sdram_config", "0x0062");
567 if (!nvram_match("debug_clkfix", "0")) {
568 dirty |= check_nv("clkfreq", "216");
570 if (dirty) {
571 nvram_set("sdram_ncdl", "0x0");
573 dirty |= check_nv("pa0itssit", "62");
574 dirty |= check_nv("pa0b0", "0x15eb");
575 dirty |= check_nv("pa0b1", "0xfa82");
576 dirty |= check_nv("pa0b2", "0xfe66");
577 //dirty |= check_nv("pa0maxpwr", "0x4e");
578 break;
579 case HW_BCM5352E: // G v4, GS v3, v4
580 dirty |= check_nv("sdram_init", "0x010b");
581 dirty |= check_nv("sdram_config", "0x0062");
582 if (dirty) {
583 nvram_set("sdram_ncdl", "0x0");
585 dirty |= check_nv("pa0itssit", "62");
586 dirty |= check_nv("pa0b0", "0x168b");
587 dirty |= check_nv("pa0b1", "0xfabf");
588 dirty |= check_nv("pa0b2", "0xfeaf");
589 //dirty |= check_nv("pa0maxpwr", "0x4e");
590 break;
591 case HW_BCM5354G:
592 dirty |= check_nv("pa0itssit", "62");
593 dirty |= check_nv("pa0b0", "0x1326");
594 dirty |= check_nv("pa0b1", "0xFB51");
595 dirty |= check_nv("pa0b2", "0xFE87");
596 //dirty |= check_nv("pa0maxpwr", "0x4e");
597 break;
598 case HW_BCM4704_BCM5325F:
599 // nothing to do
600 break;
601 default:
602 dirty |= check_nv("pa0itssit", "62");
603 dirty |= check_nv("pa0b0", "0x170c");
604 dirty |= check_nv("pa0b1", "0xfa24");
605 dirty |= check_nv("pa0b2", "0xfe70");
606 //dirty |= check_nv("pa0maxpwr", "0x48");
607 break;
609 break;
611 } // switch (model)
613 dirty |= check_nv("wl0_leddc", "0x640000");
614 dirty |= init_vlan_ports();
616 if (dirty) {
617 nvram_commit();
618 REBOOT: // do a simple reboot
619 sync();
620 reboot(RB_AUTOBOOT);
621 exit(0);
625 static int init_nvram(void)
627 unsigned long features;
628 int model;
629 const char *mfr;
630 const char *name;
631 char s[256];
632 unsigned long bf;
633 unsigned long n;
635 model = get_model();
636 sprintf(s, "%d", model);
637 nvram_set("t_model", s);
639 mfr = "Broadcom";
640 name = NULL;
641 features = 0;
642 switch (model) {
643 case MODEL_WRT54G:
644 mfr = "Linksys";
645 name = "WRT54G/GS/GL";
646 switch (check_hw_type()) {
647 case HW_BCM4712:
648 nvram_set("gpio2", "adm_eecs");
649 nvram_set("gpio3", "adm_eesk");
650 nvram_unset("gpio4");
651 nvram_set("gpio5", "adm_eedi");
652 nvram_set("gpio6", "adm_rc");
653 break;
654 case HW_BCM4702:
655 nvram_unset("gpio2");
656 nvram_unset("gpio3");
657 nvram_unset("gpio4");
658 nvram_unset("gpio5");
659 nvram_unset("gpio6");
660 break;
661 case HW_BCM5352E:
662 nvram_set("opo", "0x0008");
663 nvram_set("ag0", "0x02");
664 // drop
665 default:
666 nvram_set("gpio2", "ses_led");
667 nvram_set("gpio3", "ses_led2");
668 nvram_set("gpio4", "ses_button");
669 features = SUP_SES | SUP_WHAM_LED;
670 break;
672 break;
673 case MODEL_WTR54GS:
674 mfr = "Linksys";
675 name = "WTR54GS";
676 if (!nvram_match("t_fix1", (char *)name)) {
677 nvram_set("lan_ifnames", "vlan0 eth1");
678 nvram_set("gpio2", "ses_button");
679 nvram_set("reset_gpio", "7");
681 nvram_set("pa0itssit", "62");
682 nvram_set("pa0b0", "0x1542");
683 nvram_set("pa0b1", "0xfacb");
684 nvram_set("pa0b2", "0xfec7");
685 //nvram_set("pa0maxpwr", "0x4c");
686 features = SUP_SES;
687 break;
688 case MODEL_WRTSL54GS:
689 mfr = "Linksys";
690 name = "WRTSL54GS";
691 features = SUP_SES | SUP_WHAM_LED;
692 break;
693 case MODEL_WHRG54S:
694 mfr = "Buffalo";
695 name = "WHR-G54S";
696 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
697 break;
698 case MODEL_WHRHPG54:
699 case MODEL_WZRRSG54HP:
700 case MODEL_WZRHPG54:
701 mfr = "Buffalo";
702 features = SUP_SES | SUP_AOSS_LED | SUP_HPAMP;
703 switch (model) {
704 case MODEL_WZRRSG54HP:
705 name = "WZR-RS-G54HP";
706 break;
707 case MODEL_WZRHPG54:
708 name = "WZR-HP-G54";
709 break;
710 default:
711 name = "WHR-HP-G54";
712 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_HPAMP;
713 break;
716 bf = strtoul(nvram_safe_get("boardflags"), NULL, 0);
717 switch (bf) {
718 case 0x0758:
719 case 0x1758:
720 case 0x2758:
721 case 0x3758:
722 if (nvram_match("wlx_hpamp", "")) {
723 if (nvram_get_int("wl_txpwr") > 10) nvram_set("wl_txpwr", "10");
724 nvram_set("wlx_hpamp", "1");
725 nvram_set("wlx_hperx", "0");
728 n = bf;
729 if (nvram_match("wlx_hpamp", "0")) {
730 n &= ~0x2000UL;
732 else {
733 n |= 0x2000UL;
735 if (nvram_match("wlx_hperx", "0")) {
736 n |= 0x1000UL;
738 else {
739 n &= ~0x1000UL;
741 if (bf != n) {
742 sprintf(s, "0x%lX", n);
743 nvram_set("boardflags", s);
745 break;
746 default:
747 syslog(LOG_WARNING, "Unexpected: boardflag=%lX", bf);
748 break;
750 break;
751 case MODEL_WBRG54:
752 mfr = "Buffalo";
753 name = "WBR-G54";
754 break;
755 case MODEL_WBR2G54:
756 mfr = "Buffalo";
757 name = "WBR2-G54";
758 features = SUP_SES | SUP_AOSS_LED;
759 break;
760 case MODEL_WHR2A54G54:
761 mfr = "Buffalo";
762 name = "WHR2-A54G54";
763 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
764 break;
765 case MODEL_WHR3AG54:
766 mfr = "Buffalo";
767 name = "WHR3-AG54";
768 features = SUP_SES | SUP_AOSS_LED;
769 break;
770 case MODEL_WZRG54:
771 mfr = "Buffalo";
772 name = "WZR-G54";
773 features = SUP_SES | SUP_AOSS_LED;
774 break;
775 case MODEL_WZRRSG54:
776 mfr = "Buffalo";
777 name = "WZR-RS-G54";
778 features = SUP_SES | SUP_AOSS_LED;
779 break;
780 case MODEL_WVRG54NF:
781 mfr = "Buffalo";
782 name = "WVR-G54-NF";
783 features = SUP_SES;
784 break;
785 case MODEL_WZRG108:
786 mfr = "Buffalo";
787 name = "WZR-G108";
788 features = SUP_SES | SUP_AOSS_LED;
789 break;
790 case MODEL_RT390W:
791 mfr = "Fuji";
792 name = "RT390W";
793 break;
794 case MODEL_WR850GV1:
795 mfr = "Motorola";
796 name = "WR850G v1";
797 features = SUP_NONVE;
798 break;
799 case MODEL_WR850GV2:
800 mfr = "Motorola";
801 name = "WR850G v2/v3";
802 features = SUP_NONVE;
803 break;
804 case MODEL_WL500GP:
805 mfr = "Asus";
806 name = "WL-500gP";
807 features = SUP_SES;
808 #ifdef TCONFIG_USB
809 nvram_set("usb_ohci", "-1");
810 #endif
811 if (!nvram_match("t_fix1", (char *)name)) {
812 nvram_set("lan_ifnames", "vlan0 eth1 eth2 eth3"); // set to "vlan0 eth2" by DD-WRT; default: vlan0 eth1
814 break;
815 case MODEL_WL500W:
816 mfr = "Asus";
817 name = "WL-500W";
818 features = SUP_SES | SUP_80211N;
819 #ifdef TCONFIG_USB
820 nvram_set("usb_ohci", "-1");
821 #endif
822 break;
823 case MODEL_WL500GE:
824 mfr = "Asus";
825 name = "WL-550gE";
826 // features = ?
827 #ifdef TCONFIG_USB
828 nvram_set("usb_uhci", "-1");
829 #endif
830 break;
831 case MODEL_WX6615GT:
832 mfr = "SparkLAN";
833 name = "WX-6615GT";
834 // features = ?
835 break;
836 case MODEL_MN700:
837 mfr = "Microsoft";
838 name = "MN-700";
839 break;
840 case MODEL_WR100:
841 mfr = "Viewsonic";
842 name = "WR100";
843 break;
844 case MODEL_WLA2G54L:
845 mfr = "Buffalo";
846 name = "WLA2-G54L";
847 if (!nvram_match("t_fix1", (char *)name)) {
848 nvram_set("lan_ifnames", "vlan0 eth1 eth2");
849 nvram_set("wl_ifname", "eth1");
850 nvram_set("wan_ifname", "none");
852 break;
853 case MODEL_TM2300:
854 mfr = "Dell";
855 name = "TrueMobile 2300";
856 break;
864 #ifndef WL_BSS_INFO_VERSION
865 #error WL_BSS_INFO_VERSION
866 #endif
867 #if WL_BSS_INFO_VERSION >= 108
869 case MODEL_WRH54G:
870 mfr = "Linksys";
871 name = "WRH54G";
873 nvram_set("opo", "12");
874 break;
876 case MODEL_WHRG125:
877 mfr = "Buffalo";
878 name = "WHR-G125";
879 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
881 nvram_set("opo", "0x0008");
882 nvram_set("ag0", "0x0C");
883 break;
884 #ifdef CONFIG_BCMWL5
885 case MODEL_RTN10:
886 mfr = "Asus";
887 name = "RT-N10";
888 features = SUP_SES | SUP_80211N;
889 if (!nvram_match("t_fix1", (char *)name)) {
890 nvram_set("lan_ifnames", "vlan0 eth1");
891 nvram_set("wan_ifnameX", "vlan1");
892 nvram_set("wl_ifname", "eth1");
894 break;
895 case MODEL_RTN12:
896 mfr = "Asus";
897 name = "RT-N12";
898 features = SUP_SES | SUP_BRAU | SUP_80211N;
899 if (!nvram_match("t_fix1", (char *)name)) {
900 nvram_set("lan_ifnames", "vlan0 eth1");
901 nvram_set("wan_ifnameX", "vlan1");
902 nvram_set("wl_ifname", "eth1");
904 break;
905 case MODEL_RTN16:
906 mfr = "Asus";
907 name = "RT-N16";
908 features = SUP_SES | SUP_80211N | SUP_1000ET;
909 #ifdef TCONFIG_USB
910 nvram_set("usb_uhci", "-1");
911 #endif
912 if (!nvram_match("t_fix1", (char *)name)) {
913 nvram_set("lan_ifnames", "vlan1 eth1");
914 nvram_set("wan_ifnameX", "vlan2");
915 nvram_set("wl_ifname", "eth1");
916 nvram_set("vlan_enable", "1");
918 break;
919 case MODEL_WNR3500L:
920 mfr = "Netgear";
921 name = "WNR3500L/U/v2";
922 features = SUP_SES | SUP_AOSS_LED | SUP_80211N | SUP_1000ET;
923 if (!nvram_match("t_fix1", (char *)name)) {
924 nvram_set("sromrev", "3");
925 nvram_set("lan_ifnames", "vlan1 eth1");
926 nvram_set("wan_ifnameX", "vlan2");
927 nvram_set("wl_ifname", "eth1");
929 break;
930 case MODEL_WNR2000v2:
931 mfr = "Netgear";
932 name = "WNR2000 v2";
933 features = SUP_SES | SUP_AOSS_LED | SUP_80211N;
934 if (!nvram_match("t_fix1", (char *)name)) {
935 nvram_set("lan_ifnames", "vlan0 eth1");
936 nvram_set("wan_ifnameX", "vlan1");
937 nvram_set("wl_ifname", "eth1");
939 break;
940 case MODEL_WRT160Nv3:
941 // same as M10, WRT310Nv2
942 mfr = "Linksys";
943 name = nvram_safe_get("boot_hw_model");
944 features = SUP_SES | SUP_80211N | SUP_WHAM_LED;
945 if (!nvram_match("t_fix1", (char *)name)) {
946 nvram_set("lan_ifnames", "vlan1 eth1");
947 nvram_set("wan_ifnameX", "vlan2");
948 nvram_set("wl_ifname", "eth1");
950 break;
951 case MODEL_WRT320N:
952 mfr = "Linksys";
953 name = nvram_match("boardrev", "0x1307") ? "E2000" : "WRT320N";
954 features = SUP_SES | SUP_80211N | SUP_WHAM_LED | SUP_1000ET;
955 if (!nvram_match("t_fix1", (char *)name)) {
956 nvram_set("lan_ifnames", "vlan1 eth1");
957 nvram_set("wan_ifnameX", "vlan2");
958 nvram_set("wl_ifname", "eth1");
960 break;
961 case MODEL_WRT610Nv2:
962 mfr = "Linksys";
963 name = nvram_match("boot_hw_model", "E300") ? "E3000" : "WRT610N v2";
964 features = SUP_SES | SUP_80211N | SUP_WHAM_LED | SUP_1000ET;
965 #ifdef TCONFIG_USB
966 nvram_set("usb_uhci", "-1");
967 #endif
968 if (!nvram_match("t_fix1", (char *)name)) {
969 nvram_set("lan_ifnames", "vlan1 eth1 eth2");
970 nvram_set("wan_ifnameX", "vlan2");
971 nvram_set("wl_ifname", "eth1");
973 break;
974 #endif // CONFIG_BCMWL5
975 case MODEL_WL500GPv2:
976 mfr = "Asus";
977 name = "WL-500gP v2";
978 features = SUP_SES;
979 #ifdef TCONFIG_USB
980 nvram_set("usb_uhci", "-1");
981 #endif
982 break;
983 case MODEL_WL520GU:
984 mfr = "Asus";
985 name = "WL-520GU";
986 features = SUP_SES;
987 #ifdef TCONFIG_USB
988 nvram_set("usb_uhci", "-1");
989 #endif
990 break;
991 case MODEL_WL500GD:
992 mfr = "Asus";
993 name = "WL-500g Deluxe";
994 // features = SUP_SES;
995 #ifdef TCONFIG_USB
996 nvram_set("usb_ohci", "-1");
997 #endif
998 if (!nvram_match("t_fix1", (char *)name)) {
999 nvram_set("wl_ifname", "eth1");
1000 nvram_set("lan_ifnames", "vlan0 eth1");
1001 nvram_set("wan_ifnameX", "vlan1");
1002 nvram_unset("wl0gpio0");
1004 break;
1005 case MODEL_DIR320:
1006 mfr = "D-Link";
1007 name = "DIR-320";
1008 features = SUP_SES;
1009 if (!nvram_match("t_fix1", (char *)name)) {
1010 nvram_set("wan_ifnameX", "vlan1");
1011 nvram_set("wl_ifname", "eth1");
1013 break;
1014 case MODEL_H618B:
1015 mfr = "ZTE";
1016 name = "ZXV10 H618B";
1017 features = SUP_SES | SUP_AOSS_LED;
1018 break;
1019 case MODEL_WL1600GL:
1020 mfr = "Ovislink";
1021 name = "WL1600GL";
1022 features = SUP_SES;
1023 break;
1024 #endif // WL_BSS_INFO_VERSION >= 108
1025 case MODEL_WZRG300N:
1026 mfr = "Buffalo";
1027 name = "WZR-G300N";
1028 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_80211N;
1029 break;
1030 case MODEL_WRT160Nv1:
1031 case MODEL_WRT300N:
1032 mfr = "Linksys";
1033 name = (model == MODEL_WRT300N) ? "WRT300N v1" : "WRT160N v1";
1034 features = SUP_SES | SUP_80211N;
1035 if (!nvram_match("t_fix1", (char *)name)) {
1036 nvram_set("wan_ifnameX", "eth1");
1037 nvram_set("lan_ifnames", "eth0 eth2");
1039 break;
1040 case MODEL_WRT310Nv1:
1041 mfr = "Linksys";
1042 name = "WRT310N v1";
1043 features = SUP_SES | SUP_80211N | SUP_WHAM_LED | SUP_1000ET;
1044 if (!nvram_match("t_fix1", (char *)name)) {
1045 nvram_set("lan_ifnames", "vlan1 eth1");
1046 nvram_set("wan_ifnameX", "vlan2");
1047 nvram_set("wl_ifname", "eth1");
1049 break;
1052 if (name) {
1053 nvram_set("t_fix1", name);
1054 sprintf(s, "%s %s", mfr, name);
1056 else {
1057 snprintf(s, sizeof(s), "%s %d/%s/%s/%s/%s", mfr, check_hw_type(),
1058 nvram_safe_get("boardtype"), nvram_safe_get("boardnum"), nvram_safe_get("boardrev"), nvram_safe_get("boardflags"));
1059 s[64] = 0;
1061 nvram_set("t_model_name", s);
1063 nvram_set("pa0maxpwr", "400"); // allow Tx power up tp 400 mW, needed for ND only
1065 sprintf(s, "0x%lX", features);
1066 nvram_set("t_features", s);
1069 note: set wan_ifnameX if wan_ifname needs to be overriden
1072 if (nvram_is_empty("wan_ifnameX")) {
1073 #if 1
1074 nvram_set("wan_ifnameX", ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
1075 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1");
1076 #else
1077 p = nvram_safe_get("wan_ifname");
1078 if ((*p == 0) || (nvram_match("wl_ifname", p))) {
1079 p = ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
1080 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
1082 nvram_set("wan_ifnameX", p);
1083 #endif
1086 nvram_set("wl_hwaddr", ""); // zzz- when disabling wireless, we must get null wireless mac ??
1088 //!!TB - do not force country code here to allow nvram override
1089 //nvram_set("wl_country", "JP");
1090 //nvram_set("wl_country_code", "JP");
1091 nvram_set("wan_get_dns", "");
1092 nvram_set("wan_get_domain", "");
1093 nvram_set("pppoe_pid0", "");
1094 nvram_set("action_service", "");
1095 nvram_set("jffs2_format", "0");
1096 nvram_set("rrules_radio", "-1");
1097 nvram_unset("https_crt_gen");
1098 nvram_unset("log_wmclear");
1099 #ifdef TCONFIG_IPV6
1100 nvram_set("ipv6_get_dns", "");
1101 #endif
1102 #ifdef TCONFIG_MEDIA_SERVER
1103 nvram_unset("ms_rescan");
1104 #endif
1105 if (nvram_get_int("http_id_gen") == 1) nvram_unset("http_id");
1107 nvram_unset("sch_rboot_last");
1108 nvram_unset("sch_rcon_last");
1109 nvram_unset("sch_c1_last");
1110 nvram_unset("sch_c2_last");
1111 nvram_unset("sch_c3_last");
1113 nvram_set("brau_state", "");
1114 if ((features & SUP_BRAU) == 0) nvram_set("script_brau", "");
1115 if ((features & SUP_SES) == 0) nvram_set("sesx_script", "");
1117 if ((features & SUP_1000ET) == 0) nvram_set("jumbo_frame_enable", "0");
1119 // compatibility with old versions
1120 if (nvram_match("wl_net_mode", "disabled")) {
1121 nvram_set("wl_radio", "0");
1122 nvram_set("wl_net_mode", "mixed");
1125 return 0;
1128 /* Get the special files from nvram and copy them to disc.
1129 * These were files saved with "nvram setfile2nvram <filename>".
1130 * Better hope that they were saved with full pathname.
1132 static void load_files_from_nvram(void)
1134 char *name, *cp;
1135 int ar_loaded = 0;
1136 char buf[NVRAM_SPACE];
1138 if (nvram_getall(buf, sizeof(buf)) != 0)
1139 return;
1141 for (name = buf; *name; name += strlen(name) + 1) {
1142 if (strncmp(name, "FILE:", 5) == 0) { /* This special name marks a file to get. */
1143 if ((cp = strchr(name, '=')) == NULL)
1144 continue;
1145 *cp = 0;
1146 syslog(LOG_INFO, "Loading file '%s' from nvram", name + 5);
1147 nvram_nvram2file(name, name + 5);
1148 if (memcmp(".autorun", cp - 8, 9) == 0)
1149 ++ar_loaded;
1152 /* Start any autorun files that may have been loaded into one of the standard places. */
1153 if (ar_loaded != 0)
1154 run_nvscript(".autorun", NULL, 3);
1157 #if defined(LINUX26) && defined(TCONFIG_USB)
1158 static inline void tune_min_free_kbytes(void)
1160 struct sysinfo info;
1162 memset(&info, 0, sizeof(struct sysinfo));
1163 sysinfo(&info);
1164 if (info.totalram >= 55 * 1024 * 1024) {
1165 // If we have 64MB+ RAM, tune min_free_kbytes
1166 // to reduce page allocation failure errors.
1167 f_write_string("/proc/sys/vm/min_free_kbytes", "8192", 0, 0);
1170 #endif
1172 static void sysinit(void)
1174 static int noconsole = 0;
1175 static const time_t tm = 0;
1176 int hardware;
1177 int i;
1178 DIR *d;
1179 struct dirent *de;
1180 char s[256];
1181 char t[256];
1182 int model;
1184 mount("proc", "/proc", "proc", 0, NULL);
1185 mount("tmpfs", "/tmp", "tmpfs", 0, NULL);
1187 #ifdef LINUX26
1188 mount("devfs", "/dev", "tmpfs", MS_MGC_VAL | MS_NOATIME, NULL);
1189 mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3));
1190 mknod("/dev/console", S_IFCHR | 0600, makedev(5, 1));
1191 mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL);
1192 mkdir("/dev/shm", 0777);
1193 mkdir("/dev/pts", 0777);
1194 mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, NULL);
1195 #endif
1197 if (console_init()) noconsole = 1;
1199 stime(&tm);
1201 static const char *mkd[] = {
1202 "/tmp/etc", "/tmp/var", "/tmp/home", "/tmp/mnt",
1203 "/tmp/share", "/var/webmon", // !!TB
1204 "/var/log", "/var/run", "/var/tmp", "/var/lib", "/var/lib/misc",
1205 "/var/spool", "/var/spool/cron", "/var/spool/cron/crontabs",
1206 "/tmp/var/wwwext", "/tmp/var/wwwext/cgi-bin", // !!TB - CGI support
1207 NULL
1209 umask(0);
1210 for (i = 0; mkd[i]; ++i) {
1211 mkdir(mkd[i], 0755);
1213 mkdir("/var/lock", 0777);
1214 mkdir("/var/tmp/dhcp", 0777);
1215 mkdir("/home/root", 0700);
1216 chmod("/tmp", 0777);
1217 f_write("/etc/hosts", NULL, 0, 0, 0644); // blank
1218 f_write("/etc/fstab", NULL, 0, 0, 0644); // !!TB - blank
1219 simple_unlock("cron");
1220 simple_unlock("firewall");
1221 simple_unlock("restrictions");
1222 umask(022);
1224 if ((d = opendir("/rom/etc")) != NULL) {
1225 while ((de = readdir(d)) != NULL) {
1226 if (de->d_name[0] == '.') continue;
1227 snprintf(s, sizeof(s), "%s/%s", "/rom/etc", de->d_name);
1228 snprintf(t, sizeof(t), "%s/%s", "/etc", de->d_name);
1229 symlink(s, t);
1231 closedir(d);
1233 symlink("/proc/mounts", "/etc/mtab");
1235 #ifdef TCONFIG_SAMBASRV
1236 if ((d = opendir("/usr/codepages")) != NULL) {
1237 while ((de = readdir(d)) != NULL) {
1238 if (de->d_name[0] == '.') continue;
1239 snprintf(s, sizeof(s), "/usr/codepages/%s", de->d_name);
1240 snprintf(t, sizeof(t), "/usr/share/%s", de->d_name);
1241 symlink(s, t);
1243 closedir(d);
1245 #endif
1247 #ifdef LINUX26
1248 eval("hotplug2", "--coldplug");
1249 start_hotplug2();
1251 static const char *dn[] = {
1252 "null", "zero", "random", "urandom", "full", "ptmx", "nvram",
1253 NULL
1255 for (i = 0; dn[i]; ++i) {
1256 snprintf(s, sizeof(s), "/dev/%s", dn[i]);
1257 chmod(s, 0666);
1259 chmod("/dev/gpio", 0660);
1260 #endif
1262 set_action(ACT_IDLE);
1264 for (i = 0; defenv[i]; ++i) {
1265 putenv(defenv[i]);
1268 if (!noconsole) {
1269 printf("\n\nHit ENTER for console...\n\n");
1270 run_shell(1, 0);
1273 check_bootnv();
1275 #ifdef TCONFIG_IPV6
1276 // disable IPv6 by default on all interfaces
1277 f_write_string("/proc/sys/net/ipv6/conf/default/disable_ipv6", "1", 0, 0);
1278 #endif
1280 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++) {
1281 signal(fatalsigs[i], handle_fatalsigs);
1283 signal(SIGCHLD, handle_reap);
1285 switch (model = get_model()) {
1286 case MODEL_WR850GV1:
1287 case MODEL_WR850GV2:
1288 // need to cleanup some variables...
1289 if ((nvram_get("t_model") == NULL) && (nvram_get("MyFirmwareVersion") != NULL)) {
1290 nvram_unset("MyFirmwareVersion");
1291 nvram_set("restore_defaults", "1");
1293 break;
1296 #ifdef CONFIG_BCMWL5
1297 // ctf must be loaded prior to any other modules
1298 if (nvram_get_int("ctf_enable"))
1299 modprobe("ctf");
1300 #endif
1302 switch (hardware = check_hw_type()) {
1303 case HW_BCM4785:
1304 modprobe("bcm57xx");
1305 break;
1306 default:
1307 modprobe("et");
1308 break;
1311 #ifdef TCONFIG_EMF
1312 modprobe("emf");
1313 modprobe("igs");
1314 #endif
1315 modprobe("wl");
1317 config_loopback();
1319 system("nvram defaults --initcheck");
1320 init_nvram();
1322 // set the packet size
1323 if (nvram_get_int("jumbo_frame_enable")) {
1324 // only set the size here - 'enable' flag is set by the driver
1325 // eval("et", "robowr", "0x40", "0x01", "0x1F"); // (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)
1326 eval("et", "robowr", "0x40", "0x05", nvram_safe_get("jumbo_frame_size"));
1329 klogctl(8, NULL, nvram_get_int("console_loglevel"));
1331 #if defined(LINUX26) && defined(TCONFIG_USB)
1332 tune_min_free_kbytes();
1333 #endif
1334 setup_conntrack();
1335 set_host_domain_name();
1337 set_tz();
1339 eval("buttons");
1341 if (!noconsole) xstart("console");
1343 i = nvram_get_int("sesx_led");
1344 led(LED_AMBER, (i & 1) != 0);
1345 led(LED_WHITE, (i & 2) != 0);
1346 led(LED_AOSS, (i & 4) != 0);
1347 led(LED_BRIDGE, (i & 8) != 0);
1348 led(LED_DIAG, 1);
1351 int init_main(int argc, char *argv[])
1353 int state, i;
1354 sigset_t sigset;
1356 sysinit();
1358 sigemptyset(&sigset);
1359 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++) {
1360 sigaddset(&sigset, initsigs[i]);
1362 sigprocmask(SIG_BLOCK, &sigset, NULL);
1364 #if defined(DEBUG_NOISY)
1365 nvram_set("debug_logeval", "1");
1366 nvram_set("debug_cprintf", "1");
1367 nvram_set("debug_cprintf_file", "1");
1368 nvram_set("debug_ddns", "1");
1369 #endif
1371 start_jffs2();
1373 state = SIGUSR2; /* START */
1375 for (;;) {
1376 TRACE_PT("main loop signal/state=%d\n", state);
1378 switch (state) {
1379 case SIGUSR1: /* USER1: service handler */
1380 exec_service();
1381 break;
1383 case SIGHUP: /* RESTART */
1384 case SIGINT: /* STOP */
1385 case SIGQUIT: /* HALT */
1386 case SIGTERM: /* REBOOT */
1387 led(LED_DIAG, 1);
1388 unlink("/var/notice/sysup");
1390 run_nvscript("script_shut", NULL, 10);
1392 stop_services();
1393 stop_wan();
1394 stop_lan();
1395 stop_vlan();
1396 stop_syslog();
1398 if ((state == SIGTERM /* REBOOT */) ||
1399 (state == SIGQUIT /* HALT */)) {
1400 remove_storage_main(1);
1401 stop_usb();
1403 shutdn(state == SIGTERM /* REBOOT */);
1404 exit(0);
1406 if (state == SIGINT /* STOP */) {
1407 break;
1410 // SIGHUP (RESTART) falls through
1412 case SIGUSR2: /* START */
1413 SET_LED(RELEASE_WAN_CONTROL);
1414 start_syslog();
1416 load_files_from_nvram();
1418 int fd = -1;
1419 fd = file_lock("usb"); // hold off automount processing
1420 start_usb();
1422 run_nvscript("script_init", NULL, 2);
1424 file_unlock(fd); // allow to process usb hotplug events
1425 #ifdef TCONFIG_USB
1427 * On RESTART some partitions can stay mounted if they are busy at the moment.
1428 * In that case USB drivers won't unload, and hotplug won't kick off again to
1429 * remount those drives that actually got unmounted. Make sure to remount ALL
1430 * partitions here by simulating hotplug event.
1432 if (state == SIGHUP /* RESTART */)
1433 add_remove_usbhost("-1", 1);
1434 #endif
1436 create_passwd();
1437 start_vlan();
1438 start_lan();
1439 start_wan(BOOT);
1440 start_services();
1441 start_wl();
1443 #ifdef CONFIG_BCMWL5
1444 if (wds_enable()) {
1445 /* Restart NAS one more time - for some reason without
1446 * this the new driver doesn't always bring WDS up.
1448 stop_nas();
1449 start_nas();
1451 #endif
1453 syslog(LOG_INFO, "%s: Tomato %s", nvram_safe_get("t_model_name"), tomato_version);
1455 led(LED_DIAG, 0);
1456 notice_set("sysup", "");
1457 break;
1460 chld_reap(0); /* Periodically reap zombies. */
1461 check_services();
1462 sigwait(&sigset, &state);
1465 return 0;
1468 int reboothalt_main(int argc, char *argv[])
1470 int reboot = (strstr(argv[0], "reboot") != NULL);
1471 puts(reboot ? "Rebooting..." : "Shutting down...");
1472 fflush(stdout);
1473 sleep(1);
1474 kill(1, reboot ? SIGTERM : SIGQUIT);
1476 /* In the case we're hung, we'll get stuck and never actually reboot.
1477 * The only way out is to pull power.
1478 * So after 'reset_wait' seconds (default: 20), forcibly crash & restart.
1480 if (fork() == 0) {
1481 int wait = nvram_get_int("reset_wait") ? : 20;
1482 if ((wait < 10) || (wait > 120)) wait = 10;
1484 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1485 sleep(wait);
1486 puts("Still running... Doing machine reset.");
1487 fflush(stdout);
1488 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1489 sleep(1);
1490 f_write("/proc/sysrq-trigger", "b", 1, 0 , 0); /* machine reset */
1493 return 0;