3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
39 #include <arpa/inet.h>
44 #define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST)
45 #define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
50 // -----------------------------------------------------------------------------
52 static const char dmhosts
[] = "/etc/hosts.dnsmasq";
53 static const char dmresolv
[] = "/etc/resolv.dnsmasq";
54 static const char dmpid
[] = "/var/run/dnsmasq.pid";
56 static pid_t pid_dnsmasq
= -1;
65 const char *router_ip
;
66 const char *lan_ifname
;
70 char *mac
, *ip
, *name
;
84 start_service("dnsmasq");
90 if (nvram_match("wl_mode", "wet")) return;
91 if ((f
= fopen("/etc/dnsmasq.conf", "w")) == NULL
) return;
93 lan_ifname
= nvram_safe_get("lan_ifname");
94 router_ip
= nvram_safe_get("lan_ipaddr");
95 strlcpy(lan
, router_ip
, sizeof(lan
));
96 if ((p
= strrchr(lan
, '.')) != NULL
) *(p
+ 1) = 0;
102 if (((nv
= nvram_get("wan_domain")) != NULL
) || ((nv
= nvram_get("wan_get_domain")) != NULL
)) {
103 if (*nv
) fprintf(f
, "domain=%s\n", nv
);
107 if (((nv
= nvram_get("dns_minport")) != NULL
) && (*nv
)) n
= atoi(nv
);
110 "resolv-file=%s\n" // the real stuff is here
111 "addn-hosts=%s\n" // "
112 "expand-hosts\n" // expand hostnames in hosts file
113 "min-port=%u\n", // min port used for random src port
114 dmresolv
, dmhosts
, n
);
115 do_dns
= nvram_match("dhcpd_dmdns", "1");
119 do_dhcpd
= nvram_match("lan_proto", "dhcp");
121 dhcp_lease
= nvram_get_int("dhcp_lease");
122 if (dhcp_lease
<= 0) dhcp_lease
= 1440;
124 if ((e
= nvram_get("dhcpd_slt")) != NULL
) n
= atoi(e
); else n
= 0;
125 if (n
< 0) strcpy(sdhcp_lease
, "infinite");
126 else sprintf(sdhcp_lease
, "%dm", (n
> 0) ? n
: dhcp_lease
);
129 // if not using dnsmasq for dns
131 const dns_list_t
*dns
= get_dns(); // this always points to a static buffer
132 if ((dns
->count
== 0) && (nvram_match("dhcpd_llndns", "1"))) {
133 // no DNS might be temporary. use a low lease time to force clients to update.
135 strcpy(sdhcp_lease
, "2m");
139 // pass the dns directly
141 for (n
= 0 ; n
< dns
->count
; ++n
) {
142 sprintf(buf
+ strlen(buf
), ",%s", inet_ntoa(dns
->dns
[n
]));
144 fprintf(f
, "dhcp-option=6%s\n", buf
);
148 if ((p
= nvram_get("dhcpd_startip")) && (*p
) && (e
= nvram_get("dhcpd_endip")) && (*e
)) {
149 fprintf(f
, "dhcp-range=%s,%s,%s,%dm\n", p
, e
, nvram_safe_get("lan_netmask"), dhcp_lease
);
153 dhcp_start
= nvram_get_int("dhcp_start");
154 dhcp_count
= nvram_get_int("dhcp_num");
155 fprintf(f
, "dhcp-range=%s%d,%s%d,%s,%dm\n",
156 lan
, dhcp_start
, lan
, dhcp_start
+ dhcp_count
- 1, nvram_safe_get("lan_netmask"), dhcp_lease
);
158 n
= nvram_get_int("dhcpd_lmax");
160 "dhcp-option=3,%s\n" // gateway
161 "dhcp-lease-max=%d\n",
165 if (nvram_get_int("dhcpd_auth") >= 0) {
166 fprintf(f
, "dhcp-authoritative\n");
169 if (((nv
= nvram_get("wan_wins")) != NULL
) && (*nv
) && (strcmp(nv
, "0.0.0.0") != 0)) {
170 fprintf(f
, "dhcp-option=44,%s\n", nv
);
174 fprintf(f
, "no-dhcp-interface=%s\n", lan_ifname
);
177 // write static lease entries & create hosts file
179 if ((hf
= fopen(dmhosts
, "w")) != NULL
) {
180 if (((nv
= nvram_get("wan_hostname")) != NULL
) && (*nv
))
181 fprintf(hf
, "%s %s\n", router_ip
, nv
);
184 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
185 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
186 p
= nvram_safe_get("dhcpd_static");
187 while ((e
= strchr(p
, '>')) != NULL
) {
198 if ((e
= strchr(buf
, '<')) == NULL
) continue;
203 if ((e
= strchr(ip
, '<')) == NULL
) continue;
205 if (strchr(ip
, '.') == NULL
) {
207 if ((ipn
<= 0) || (ipn
> 255)) continue;
208 sprintf(ipbuf
, "%s%d", lan
, ipn
);
212 if (inet_addr(ip
) == INADDR_NONE
) continue;
217 if ((hf
) && (*name
!= 0)) {
218 fprintf(hf
, "%s %s\n", ip
, name
);
221 if ((do_dhcpd
) && (*mac
!= 0) && (strcmp(mac
, "00:00:00:00:00:00") != 0)) {
222 fprintf(f
, "dhcp-host=%s,%s,%s\n", mac
, ip
, sdhcp_lease
);
230 fprintf(f
, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
232 fappend(f
, "/etc/dnsmasq.custom");
239 unlink("/etc/resolv.conf");
240 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
243 TRACE_PT("run dnsmasq\n");
247 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
248 f_read_string(dmpid
, buf
, sizeof(buf
));
249 pid_dnsmasq
= atol(buf
);
255 void stop_dnsmasq(void)
260 stop_service("dnsmasq");
266 unlink("/etc/resolv.conf");
267 symlink(dmresolv
, "/etc/resolv.conf");
269 killall_tk("dnsmasq");
274 void clear_resolv(void)
276 _dprintf("%s\n", __FUNCTION__
);
278 f_write(dmresolv
, NULL
, 0, 0, 0); // blank
281 void dns_to_resolv(void)
284 const dns_list_t
*dns
;
288 _dprintf("%s\n", __FUNCTION__
);
290 m
= umask(022); // 077 from pppoecd
291 if ((f
= fopen(dmresolv
, "w")) != NULL
) {
292 dns
= get_dns(); // static buffer
293 if (dns
->count
== 0) {
294 // Put a pseudo DNS IP to trigger Connect On Demand
295 if ((nvram_match("ppp_demand", "1")) &&
296 (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp") || nvram_match("wan_proto", "l2tp"))) {
297 fprintf(f
, "nameserver 1.1.1.1\n");
301 for (i
= 0; i
< dns
->count
; i
++) {
302 fprintf(f
, "nameserver %s\n", inet_ntoa(dns
->dns
[i
]));
310 // -----------------------------------------------------------------------------
312 void start_httpd(void)
315 if (!nvram_match("http_enable", "0")) {
318 if (!nvram_match("https_enable", "0")) {
319 xstart("httpd", "-s");
324 void stop_httpd(void)
329 // -----------------------------------------------------------------------------
331 void start_upnp(void)
333 if (get_wan_proto() == WP_DISABLED
) return;
340 if (((enable
= nvram_get_int("upnp_enable")) & 3) != 0) {
341 mkdir("/etc/upnp", 0777);
342 if (f_exists("/etc/upnp/config.alt")) {
343 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
346 if ((f
= fopen("/etc/upnp/config", "w")) != NULL
) {
347 upnp_port
= nvram_get_int("upnp_port");
348 if ((upnp_port
<= 0) || (upnp_port
>= 0xFFFF)) upnp_port
= 5000;
357 "upnp_forward_chain=upnp\n"
358 "upnp_nat_chain=upnp\n"
359 "system_uptime=yes\n"
362 nvram_safe_get("wan_iface"),
363 nvram_safe_get("lan_ipaddr"),
365 (enable
& 1) ? "yes" : "no", // upnp enable
366 (enable
& 2) ? "yes" : "no", // natpmp enable
367 nvram_get_int("upnp_secure") ? "yes" : "no" // secure_mode (only forward to self)
369 fappend(f
, "/etc/upnp/config.custom");
372 xstart("miniupnpd", "-f", "/etc/upnp/config");
377 if (nvram_get_int("upnp_enable")) {
380 "-L", nvram_safe_get("lan_ifname"),
381 "-W", nvram_safe_get("wan_iface"),
382 "-I", nvram_safe_get("upnp_ssdp_interval"),
383 "-A", nvram_safe_get("upnp_max_age"));
391 killall_tk("miniupnpd");
397 // -----------------------------------------------------------------------------
399 static pid_t pid_crond
= -1;
401 void start_cron(void)
403 char *argv
[] = { "crond", "-l", "9", NULL
};
407 if (nvram_contains_word("log_events", "crond")) argv
[1] = NULL
;
408 _eval(argv
, NULL
, 0, NULL
);
409 if (!nvram_contains_word("debug_norestart", "crond")) {
421 // -----------------------------------------------------------------------------
423 // Written by Sparq in 2002/07/16
424 void start_zebra(void)
429 char *lan_tx
= nvram_safe_get("dr_lan_tx");
430 char *lan_rx
= nvram_safe_get("dr_lan_rx");
431 char *wan_tx
= nvram_safe_get("dr_wan_tx");
432 char *wan_rx
= nvram_safe_get("dr_wan_rx");
434 if ((*lan_tx
== '0') && (*lan_rx
== '0') && (*wan_tx
== '0') && (*wan_rx
== '0')) {
439 if ((fp
= fopen("/etc/zebra.conf", "w")) != NULL
) {
444 if ((fp
= fopen("/etc/ripd.conf", "w")) != NULL
) {
445 char *lan_ifname
= nvram_safe_get("lan_ifname");
446 char *wan_ifname
= nvram_safe_get("wan_ifname");
448 fprintf(fp
, "router rip\n");
449 fprintf(fp
, "network %s\n", lan_ifname
);
450 fprintf(fp
, "network %s\n", wan_ifname
);
451 fprintf(fp
, "redistribute connected\n");
452 //fprintf(fp, "redistribute static\n");
454 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
455 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
457 fprintf(fp
, "interface %s\n", lan_ifname
);
458 if (*lan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan_tx
);
459 if (*lan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan_rx
);
461 fprintf(fp
, "interface %s\n", wan_ifname
);
462 if (*wan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", wan_tx
);
463 if (*wan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", wan_rx
);
465 fprintf(fp
, "router rip\n");
466 if (*lan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan_ifname
);
467 if (*lan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan_ifname
);
468 if (*wan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", wan_ifname
);
469 if (*wan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", wan_ifname
);
470 fprintf(fp
, "access-list private deny any\n");
472 //fprintf(fp, "debug rip events\n");
473 //fprintf(fp, "log file /etc/ripd.log\n");
477 xstart("zebra", "-d", "-f", "/etc/zebra.conf");
478 xstart("ripd", "-d", "-f", "/etc/ripd.conf");
482 void stop_zebra(void)
485 killall("zebra", SIGTERM
);
486 killall("ripd", SIGTERM
);
488 unlink("/etc/zebra.conf");
489 unlink("/etc/ripd.conf");
493 // -----------------------------------------------------------------------------
495 void start_syslog(void)
508 if (nvram_match("log_remote", "1")) {
509 nv
= nvram_safe_get("log_remoteip");
511 snprintf(rem
, sizeof(rem
), "%s:%s", nv
, nvram_safe_get("log_remoteport"));
517 if (nvram_match("log_file", "1")) {
525 _eval(argv
, NULL
, 0, NULL
);
530 _eval(argv
, NULL
, 0, NULL
);
533 // used to be available in syslogd -m
534 n
= nvram_get_int("log_mark");
536 sprintf(s
, "cru a syslogdmark \"%s %s * * * logger -p syslog.info -- -- MARK --\"",
537 (n
< 60) ? "*/30" : "0", (n
< 120) ? "*" : "*/2");
541 system("cru d syslogdmark");
553 argv
[2] = nvram_get("log_mark");
556 if (nvram_match("log_remote", "1")) {
557 nv
= nvram_safe_get("log_remoteip");
559 snprintf(rem
, sizeof(rem
), "%s:%s", nv
, nvram_safe_get("log_remoteport"));
565 if (nvram_match("log_file", "1")) {
573 _eval(argv
, NULL
, 0, NULL
);
578 _eval(argv
, NULL
, 0, NULL
);
584 void stop_syslog(void)
586 killall("klogd", SIGTERM
);
587 killall("syslogd", SIGTERM
);
590 // -----------------------------------------------------------------------------
592 static pid_t pid_igmp
= -1;
594 void start_igmp_proxy(void)
599 if (nvram_match("multicast_pass", "1")) {
600 switch (get_wan_proto()) {
610 xstart("igmprt", "-f", "-i", nvram_safe_get(p
));
612 if (!nvram_contains_word("debug_norestart", "igmprt")) {
618 void stop_igmp_proxy(void)
621 killall("igmprt", SIGTERM
);
625 // -----------------------------------------------------------------------------
629 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE
|FW_NEWLINE
, 0644);
632 void start_ntpc(void)
638 if (nvram_get_int("ntp_updates") >= 0) {
639 xstart("ntpsync", "--init");
645 killall("ntpsync", SIGTERM
);
648 // -----------------------------------------------------------------------------
650 static void stop_rstats(void)
656 while ((n
-- > 0) && ((pid
= pidof("rstats")) > 0)) {
657 if (kill(pid
, SIGTERM
) != 0) break;
662 static void start_rstats(int new)
664 if (nvram_match("rstats_enable", "1")) {
666 if (new) xstart("rstats", "--new");
667 else xstart("rstats");
671 // -----------------------------------------------------------------------------
673 static void _check(pid_t
*pid
, const char *name
, void (*func
)(void) )
676 if (kill(*pid
, 0) != 0) {
677 if ((*pid
= pidof(name
)) == -1) func();
682 void check_services(void)
684 _check(&pid_dnsmasq
, "dnsmasq", start_dnsmasq
);
685 _check(&pid_crond
, "crond", start_cron
);
686 _check(&pid_igmp
, "igmprt", start_igmp_proxy
);
689 // -----------------------------------------------------------------------------
691 void start_services(void)
699 if (nvram_get_int("telnetd_eas")) start_telnetd();
700 if (nvram_get_int("sshd_eas")) start_sshd();
721 void stop_services(void)
743 // -----------------------------------------------------------------------------
745 void exec_service(void)
747 const int A_START
= 1;
748 const int A_STOP
= 2;
749 const int A_RESTART
= 1|2;
757 strlcpy(buffer
, nvram_safe_get("action_service"), sizeof(buffer
));
761 act
= strsep(&next
, ",");
762 service
= strsep(&act
, "-");
768 TRACE_PT("service=%s action=%s\n", service
, act
);
770 if (strcmp(act
, "start") == 0) action
= A_START
;
771 else if (strcmp(act
, "stop") == 0) action
= A_STOP
;
772 else if (strcmp(act
, "restart") == 0) action
= A_RESTART
;
776 if (strcmp(service
, "dhcpc") == 0) {
777 if (action
& A_STOP
) stop_dhcpc();
778 if (action
& A_START
) start_dhcpc();
782 if ((strcmp(service
, "dhcpd") == 0) || (strcmp(service
, "dns") == 0) || (strcmp(service
, "dnsmasq") == 0)) {
783 if (action
& A_STOP
) stop_dnsmasq();
784 if (action
& A_START
) {
791 if (strcmp(service
, "firewall") == 0) {
792 if (action
& A_STOP
) {
796 if (action
& A_START
) {
803 if (strcmp(service
, "restrict") == 0) {
804 if (action
& A_STOP
) {
807 if (action
& A_START
) {
808 i
= nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
812 // if radio was disabled by access restriction, but no rule is handling it now, enable it
814 if (nvram_get_int("rrules_radio") < 0) {
815 if (!get_radio()) eval("radio", "on");
822 if (strcmp(service
, "qos") == 0) {
823 if (action
& A_STOP
) {
826 stop_firewall(); start_firewall(); // always restarted
827 if (action
& A_START
) {
829 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
834 if (strcmp(service
, "upnp") == 0) {
835 if (action
& A_STOP
) {
838 stop_firewall(); start_firewall(); // always restarted
839 if (action
& A_START
) {
845 if (strcmp(service
, "telnetd") == 0) {
846 if (action
& A_STOP
) stop_telnetd();
847 if (action
& A_START
) start_telnetd();
851 if (strcmp(service
, "sshd") == 0) {
852 if (action
& A_STOP
) stop_sshd();
853 if (action
& A_START
) start_sshd();
857 if (strcmp(service
, "httpd") == 0) {
858 if (action
& A_STOP
) stop_httpd();
859 if (action
& A_START
) start_httpd();
863 if (strcmp(service
, "admin") == 0) {
864 if (action
& A_STOP
) {
869 stop_firewall(); start_firewall(); // always restarted
870 if (action
& A_START
) {
873 if (nvram_match("telnetd_eas", "1")) start_telnetd();
874 if (nvram_match("sshd_eas", "1")) start_sshd();
879 if (strcmp(service
, "ddns") == 0) {
880 if (action
& A_STOP
) stop_ddns();
881 if (action
& A_START
) start_ddns();
885 if (strcmp(service
, "ntpc") == 0) {
886 if (action
& A_STOP
) stop_ntpc();
887 if (action
& A_START
) start_ntpc();
891 if (strcmp(service
, "logging") == 0) {
892 if (action
& A_STOP
) {
896 stop_firewall(); start_firewall(); // always restarted
897 if (action
& A_START
) {
904 if (strcmp(service
, "crond") == 0) {
905 if (action
& A_STOP
) {
908 if (action
& A_START
) {
914 if (strcmp(service
, "upgrade") == 0) {
915 if (action
& A_START
) {
927 killall("rstats", SIGTERM
);
928 killall("buttons", SIGTERM
);
935 if (strcmp(service
, "cifs") == 0) {
936 if (action
& A_STOP
) stop_cifs();
937 if (action
& A_START
) start_cifs();
943 if (strcmp(service
, "jffs2") == 0) {
944 if (action
& A_STOP
) stop_jffs2();
945 if (action
& A_START
) start_jffs2();
950 if (strcmp(service
, "routing") == 0) {
951 if (action
& A_STOP
) {
953 do_static_routes(0); // remove old '_saved'
954 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
958 if (action
& A_START
) {
959 do_static_routes(1); // add new
961 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
966 if (strcmp(service
, "ctnf") == 0) {
967 if (action
& A_START
) {
975 if (strcmp(service
, "wan") == 0) {
976 if (action
& A_STOP
) {
977 if (get_wan_proto() == WP_PPPOE
) {
980 stop_singe_pppoe(PPPOE0
);
981 if (((action
& A_START
) == 0) && (nvram_match("ppp_demand", "1"))) {
992 if (action
& A_START
) {
993 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
995 if (get_wan_proto() == WP_PPPOE
) {
996 stop_singe_pppoe(PPPOE0
);
998 if (nvram_invmatch("ppp_demand", "1")) {
1011 if (strcmp(service
, "net") == 0) {
1012 if (action
& A_STOP
) {
1017 if (action
& A_START
) {
1025 if (strcmp(service
, "rstats") == 0) {
1026 if (action
& A_STOP
) stop_rstats();
1027 if (action
& A_START
) start_rstats(0);
1031 if (strcmp(service
, "rstatsnew") == 0) {
1032 if (action
& A_STOP
) stop_rstats();
1033 if (action
& A_START
) start_rstats(1);
1037 if (strcmp(service
, "sched") == 0) {
1038 if (action
& A_STOP
) stop_sched();
1039 if (action
& A_START
) start_sched();
1046 // some functions check action_service and must be cleared at end -- zzz
1047 nvram_set("action_service", "");
1050 static void do_service(const char *name
, const char *action
, int user
)
1056 while (!nvram_match("action_service", "")) {
1061 else if (--n
< 0) break;
1065 snprintf(s
, sizeof(s
), "%s-%s", name
, action
);
1066 nvram_set("action_service", s
);
1070 while (nvram_match("action_service", s
)) {
1082 int service_main(int argc
, char *argv
[])
1084 if (argc
!= 3) usage_exit(argv
[0], "<service> <action>");
1085 do_service(argv
[1], argv
[2], 1);
1086 printf("\nDone.\n");
1090 void start_service(const char *name
)
1092 do_service(name
, "start", 0);
1095 void stop_service(const char *name
)
1097 do_service(name
, "stop", 0);
1101 void restart_service(const char *name)
1103 do_service(name, "restart", 0);