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-2008 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)
49 // -----------------------------------------------------------------------------
51 static const char dmhosts
[] = "/etc/hosts.dnsmasq";
52 static const char dmresolv
[] = "/etc/resolv.dnsmasq";
53 static const char dmpid
[] = "/var/run/dnsmasq.pid";
55 static pid_t pid_dnsmasq
= -1;
64 const char *router_ip
;
65 const char *lan_ifname
;
69 char *mac
, *ip
, *name
;
81 start_service("dnsmasq");
87 if (nvram_match("wl_mode", "wet")) return;
89 if (nvram_get_int("dnsmasq_norw")) {
90 if (f_exists("/etc/dnsmasq.conf")) {
91 syslog(LOG_INFO, "%s exists. Not rewriting.", "/etc/dnsmasq.conf");
96 if ((f
= fopen("/etc/dnsmasq.conf", "w")) == NULL
) return;
98 lan_ifname
= nvram_safe_get("lan_ifname");
99 router_ip
= nvram_safe_get("lan_ipaddr");
100 strlcpy(lan
, router_ip
, sizeof(lan
));
101 if ((p
= strrchr(lan
, '.')) != NULL
) *(p
+ 1) = 0;
107 if (((nv
= nvram_get("wan_domain")) != NULL
) || ((nv
= nvram_get("wan_get_domain")) != NULL
)) {
108 if (*nv
) fprintf(f
, "domain=%s\n", nv
);
112 if (((nv
= nvram_get("dns_minport")) != NULL
) && (*nv
)) n
= atoi(nv
);
115 "resolv-file=%s\n" // the real stuff is here
116 "addn-hosts=%s\n" // "
117 "expand-hosts\n" // expand hostnames in hosts file
118 "min-port=%u\n", // min port used for random src port
119 dmresolv
, dmhosts
, n
);
120 do_dns
= nvram_match("dhcpd_dmdns", "1");
124 do_dhcpd
= nvram_match("lan_proto", "dhcp");
126 dhcp_lease
= nvram_get_int("dhcp_lease");
127 if (dhcp_lease
<= 0) dhcp_lease
= 1440;
129 if ((e
= nvram_get("dhcpd_slt")) != NULL
) n
= atoi(e
); else n
= 0;
130 if (n
< 0) strcpy(sdhcp_lease
, "infinite");
131 else sprintf(sdhcp_lease
, "%dm", (n
> 0) ? n
: dhcp_lease
);
134 // if not using dnsmasq for dns
136 const dns_list_t
*dns
= get_dns(); // this always points to a static buffer
137 if ((dns
->count
== 0) && (nvram_match("dhcpd_llndns", "1"))) {
138 // no DNS might be temporary. use a low lease time to force clients to update.
140 strcpy(sdhcp_lease
, "2m");
144 // pass the dns directly
146 for (n
= 0 ; n
< dns
->count
; ++n
) {
147 sprintf(buf
+ strlen(buf
), ",%s", inet_ntoa(dns
->dns
[n
]));
149 fprintf(f
, "dhcp-option=6%s\n", buf
);
153 dhcp_start
= nvram_get_int("dhcp_start");
154 dhcp_count
= nvram_get_int("dhcp_num");
156 "dhcp-range=%s%d,%s%d,%s,%dm\n" // lease config
157 "dhcp-option=3,%s\n" // gateway
158 "dhcp-authoritative\n", // this is the authoritative server - handle all requests
159 lan
, dhcp_start
, lan
, dhcp_start
+ dhcp_count
- 1, nvram_safe_get("lan_netmask"), dhcp_lease
,
163 // avoid leasing wan ip incase the modem gives an ip in our range
164 fprintf(f
, "dhcp-host=01:02:03:04:05:06,%s\n", nvram_safe_get("wan_ipaddr"));
167 if (((nv
= nvram_get("wan_wins")) != NULL
) && (*nv
) && (strcmp(nv
, "0.0.0.0") != 0)) {
168 fprintf(f
, "dhcp-option=44,%s\n", nv
);
172 fprintf(f
, "no-dhcp-interface=%s\n", lan_ifname
);
175 // write static lease entries & create hosts file
177 if ((hf
= fopen(dmhosts
, "w")) != NULL
) {
178 if (((nv
= nvram_get("wan_hostname")) != NULL
) && (*nv
))
179 fprintf(hf
, "%s %s\n", router_ip
, nv
);
182 p
= nvram_safe_get("dhcpd_static"); // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
183 while ((e
= strchr(p
, '>')) != NULL
) {
194 if ((e
= strchr(buf
, '<')) == NULL
) continue;
199 if ((e
= strchr(ip
, '<')) == NULL
) continue;
201 if (strchr(ip
, '.') == NULL
) {
203 if ((ipn
<= 0) || (ipn
> 255)) continue;
204 sprintf(ipbuf
, "%s%d", lan
, ipn
);
208 if (inet_addr(ip
) == INADDR_NONE
) continue;
213 if ((hf
) && (*name
!= 0)) {
214 fprintf(hf
, "%s %s\n", ip
, name
);
217 if ((do_dhcpd
) && (*mac
!= 0) && (strcmp(mac
, "00:00:00:00:00:00") != 0)) {
218 fprintf(f
, "dhcp-host=%s,%s,%s\n", mac
, ip
, sdhcp_lease
);
226 fprintf(f
, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
233 if ((af
= fopen("/etc/dnsmasq.custom", "r")) != NULL
) {
234 while ((n
= fread(buf
, 1, sizeof(buf
), af
)) > 0) {
235 fwrite(buf
, 1, n
, f
);
245 unlink("/etc/resolv.conf");
246 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
252 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
253 f_read_string(dmpid
, buf
, sizeof(buf
));
254 pid_dnsmasq
= atol(buf
);
258 void stop_dnsmasq(void)
261 stop_service("dnsmasq");
267 unlink("/etc/resolv.conf");
268 symlink(dmresolv
, "/etc/resolv.conf");
270 killall_tk("dnsmasq");
273 void clear_resolv(void)
275 _dprintf("%s\n", __FUNCTION__
);
277 f_write(dmresolv
, NULL
, 0, 0, 0); // blank
280 void dns_to_resolv(void)
283 const dns_list_t
*dns
;
287 _dprintf("%s\n", __FUNCTION__
);
289 m
= umask(022); // 077 from pppoecd
290 if ((f
= fopen(dmresolv
, "w")) != NULL
) {
291 dns
= get_dns(); // static buffer
292 if (dns
->count
== 0) {
293 // Put a pseudo DNS IP to trigger Connect On Demand
294 if ((nvram_match("ppp_demand", "1")) &&
295 (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp") || nvram_match("wan_proto", "l2tp"))) {
296 fprintf(f
, "nameserver 1.1.1.1\n");
300 for (i
= 0; i
< dns
->count
; i
++) {
301 fprintf(f
, "nameserver %s\n", inet_ntoa(dns
->dns
[i
]));
309 // -----------------------------------------------------------------------------
311 void start_httpd(void)
314 if (!nvram_match("http_enable", "0")) {
317 if (!nvram_match("https_enable", "0")) {
318 xstart("httpd", "-s");
323 void stop_httpd(void)
328 // -----------------------------------------------------------------------------
330 void start_upnp(void)
332 if ((nvram_match("upnp_enable", "1")) && (get_wan_proto() != WP_DISABLED
)) {
335 "-i", nvram_safe_get("wan_iface"),
336 "-a", nvram_safe_get("lan_ipaddr"),
342 "-L", nvram_safe_get("lan_ifname"),
343 "-W", nvram_safe_get("wan_iface"),
344 "-I", nvram_safe_get("upnp_ssdp_interval"),
345 "-A", nvram_safe_get("upnp_max_age"));
353 killall_tk("miniupnpd");
359 // -----------------------------------------------------------------------------
361 static pid_t pid_crond
= -1;
363 void start_cron(void)
365 _dprintf("%s\n", __FUNCTION__
);
369 char *argv
[] = { "crond", "-l", "9", NULL
};
371 if (nvram_contains_word("log_events", "crond")) argv
[1] = NULL
;
372 _eval(argv
, NULL
, 0, NULL
);
374 if (!nvram_contains_word("debug_norestart", "crond")) {
375 pid_crond
= -2; // intentionally fail test_cron()
382 _dprintf("%s\n", __FUNCTION__
);
388 // -----------------------------------------------------------------------------
390 // Written by Sparq in 2002/07/16
391 void start_zebra(void)
396 char *lan_tx
= nvram_safe_get("dr_lan_tx");
397 char *lan_rx
= nvram_safe_get("dr_lan_rx");
398 char *wan_tx
= nvram_safe_get("dr_wan_tx");
399 char *wan_rx
= nvram_safe_get("dr_wan_rx");
401 if ((*lan_tx
== '0') && (*lan_rx
== '0') && (*wan_tx
== '0') && (*wan_rx
== '0')) {
406 if ((fp
= fopen("/etc/zebra.conf", "w")) != NULL
) {
411 if ((fp
= fopen("/etc/ripd.conf", "w")) != NULL
) {
412 char *lan_ifname
= nvram_safe_get("lan_ifname");
413 char *wan_ifname
= nvram_safe_get("wan_ifname");
415 fprintf(fp
, "router rip\n");
416 fprintf(fp
, "network %s\n", lan_ifname
);
417 fprintf(fp
, "network %s\n", wan_ifname
);
418 fprintf(fp
, "redistribute connected\n");
419 //fprintf(fp, "redistribute static\n");
421 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
422 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
424 fprintf(fp
, "interface %s\n", lan_ifname
);
425 if (*lan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan_tx
);
426 if (*lan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan_rx
);
428 fprintf(fp
, "interface %s\n", wan_ifname
);
429 if (*wan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", wan_tx
);
430 if (*wan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", wan_rx
);
432 fprintf(fp
, "router rip\n");
433 if (*lan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan_ifname
);
434 if (*lan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan_ifname
);
435 if (*wan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", wan_ifname
);
436 if (*wan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", wan_ifname
);
437 fprintf(fp
, "access-list private deny any\n");
439 //fprintf(fp, "debug rip events\n");
440 //fprintf(fp, "log file /etc/ripd.log\n");
444 xstart("zebra", "-d", "-f", "/etc/zebra.conf");
445 xstart("ripd", "-d", "-f", "/etc/ripd.conf");
449 void stop_zebra(void)
452 killall("zebra", SIGTERM
);
453 killall("ripd", SIGTERM
);
455 unlink("/etc/zebra.conf");
456 unlink("/etc/ripd.conf");
460 // -----------------------------------------------------------------------------
462 void start_syslog(void)
471 argv
[2] = nvram_get("log_mark");
474 if (nvram_match("log_remote", "1")) {
475 nv
= nvram_safe_get("log_remoteip");
477 snprintf(rem
, sizeof(rem
), "%s:%s", nv
, nvram_safe_get("log_remoteport"));
483 if (nvram_match("log_file", "1")) {
491 _eval(argv
, NULL
, 0, NULL
);
496 _eval(argv
, NULL
, 0, NULL
);
501 void stop_syslog(void)
503 killall("klogd", SIGTERM
);
504 killall("syslogd", SIGTERM
);
507 // -----------------------------------------------------------------------------
509 static pid_t pid_igmp
= -1;
511 void start_igmp_proxy(void)
516 if (nvram_match("multicast_pass", "1")) {
517 switch (get_wan_proto()) {
527 xstart("igmprt", "-f", "-i", nvram_safe_get(p
));
529 if (!nvram_contains_word("debug_norestart", "igmprt")) {
535 void stop_igmp_proxy(void)
538 killall("igmprt", SIGTERM
);
542 // -----------------------------------------------------------------------------
546 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE
|FW_NEWLINE
, 0644);
549 void start_ntpc(void)
555 if (nvram_get_int("ntp_updates") >= 0) {
556 xstart("ntpsync", "--init");
562 killall("ntpsync", SIGTERM
);
565 // -----------------------------------------------------------------------------
567 static void stop_rstats(void)
573 while ((n
-- > 0) && ((pid
= pidof("rstats")) > 0)) {
574 if (kill(pid
, SIGTERM
) != 0) break;
579 static void start_rstats(int new)
581 if (nvram_match("rstats_enable", "1")) {
583 if (new) xstart("rstats", "--new");
584 else xstart("rstats");
588 // -----------------------------------------------------------------------------
590 static void _check(pid_t
*pid
, const char *name
, void (*func
)(void) )
593 if (kill(*pid
, 0) != 0) {
594 if ((*pid
= pidof(name
)) == -1) func();
599 void check_services(void)
601 _check(&pid_dnsmasq
, "dnsmasq", start_dnsmasq
);
602 _check(&pid_crond
, "crond", start_cron
);
603 _check(&pid_igmp
, "igmprt", start_igmp_proxy
);
606 // -----------------------------------------------------------------------------
608 void start_services(void)
616 if (nvram_match("telnetd_eas", "1")) start_telnetd();
617 if (nvram_match("sshd_eas", "1")) start_sshd();
638 void stop_services(void)
660 // -----------------------------------------------------------------------------
662 void exec_service(void)
664 const int A_START
= 1;
665 const int A_STOP
= 2;
666 const int A_RESTART
= 1|2;
674 strlcpy(buffer
, nvram_safe_get("action_service"), sizeof(buffer
));
678 act
= strsep(&next
, ",");
679 service
= strsep(&act
, "-");
685 if (strcmp(act
, "start") == 0) action
= A_START
;
686 else if (strcmp(act
, "stop") == 0) action
= A_STOP
;
687 else if (strcmp(act
, "restart") == 0) action
= A_RESTART
;
690 _dprintf("%s %s service=%s action=%s\n", __FILE__
, __FUNCTION__
, service
, act
);
693 if (strcmp(service
, "dhcpc") == 0) {
694 if (action
& A_STOP
) stop_dhcpc();
695 if (action
& A_START
) start_dhcpc();
699 if ((strcmp(service
, "dhcpd") == 0) || (strcmp(service
, "dns") == 0) || (strcmp(service
, "dnsmasq") == 0)) {
700 if (action
& A_STOP
) stop_dnsmasq();
701 if (action
& A_START
) {
708 if (strcmp(service
, "firewall") == 0) {
709 if (action
& A_STOP
) {
713 if (action
& A_START
) {
720 if (strcmp(service
, "restrict") == 0) {
721 if (action
& A_STOP
) {
724 if (action
& A_START
) {
725 i
= nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
729 // if radio was disabled by access restriction, but no rule is handling it now, enable it
731 if (nvram_get_int("rrules_radio") < 0) {
732 if (!get_radio()) eval("radio", "on");
739 if (strcmp(service
, "qos") == 0) {
740 if (action
& A_STOP
) {
743 stop_firewall(); start_firewall(); // always restarted
744 if (action
& A_START
) {
746 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
751 if (strcmp(service
, "upnp") == 0) {
752 if (action
& A_STOP
) {
755 stop_firewall(); start_firewall(); // always restarted
756 if (action
& A_START
) {
762 if (strcmp(service
, "telnetd") == 0) {
763 if (action
& A_STOP
) stop_telnetd();
764 if (action
& A_START
) start_telnetd();
768 if (strcmp(service
, "sshd") == 0) {
769 if (action
& A_STOP
) stop_sshd();
770 if (action
& A_START
) start_sshd();
774 if (strcmp(service
, "admin") == 0) {
775 if (action
& A_STOP
) {
780 stop_firewall(); start_firewall(); // always restarted
781 if (action
& A_START
) {
784 if (nvram_match("telnetd_eas", "1")) start_telnetd();
785 if (nvram_match("sshd_eas", "1")) start_sshd();
790 if (strcmp(service
, "ddns") == 0) {
791 if (action
& A_STOP
) stop_ddns();
792 if (action
& A_START
) start_ddns();
796 if (strcmp(service
, "ntpc") == 0) {
797 if (action
& A_STOP
) stop_ntpc();
798 if (action
& A_START
) start_ntpc();
802 if (strcmp(service
, "logging") == 0) {
803 if (action
& A_STOP
) {
807 stop_firewall(); start_firewall(); // always restarted
808 if (action
& A_START
) {
815 if (strcmp(service
, "crond") == 0) {
816 if (action
& A_STOP
) {
819 if (action
& A_START
) {
825 if (strcmp(service
, "upgrade") == 0) {
826 if (action
& A_START
) {
838 killall("rstats", SIGTERM
);
839 killall("buttons", SIGTERM
);
846 if (strcmp(service
, "cifs") == 0) {
847 if (action
& A_STOP
) stop_cifs();
848 if (action
& A_START
) start_cifs();
854 if (strcmp(service
, "jffs2") == 0) {
855 if (action
& A_STOP
) stop_jffs2();
856 if (action
& A_START
) start_jffs2();
861 if (strcmp(service
, "routing") == 0) {
862 if (action
& A_STOP
) {
864 do_static_routes(0); // remove old '_saved'
865 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
869 if (action
& A_START
) {
870 do_static_routes(1); // add new
872 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
877 if (strcmp(service
, "ctnf") == 0) {
878 if (action
& A_START
) {
886 if (strcmp(service
, "wan") == 0) {
887 if (action
& A_STOP
) {
888 if (get_wan_proto() == WP_PPPOE
) {
891 stop_singe_pppoe(PPPOE0
);
892 if (((action
& A_START
) == 0) && (nvram_match("ppp_demand", "1"))) {
903 if (action
& A_START
) {
904 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
906 if (get_wan_proto() == WP_PPPOE
) {
907 stop_singe_pppoe(PPPOE0
);
909 if (nvram_invmatch("ppp_demand", "1")) {
922 if (strcmp(service
, "net") == 0) {
923 if (action
& A_STOP
) {
928 if (action
& A_START
) {
936 if (strcmp(service
, "rstats") == 0) {
937 if (action
& A_STOP
) stop_rstats();
938 if (action
& A_START
) start_rstats(0);
942 if (strcmp(service
, "rstatsnew") == 0) {
943 if (action
& A_STOP
) stop_rstats();
944 if (action
& A_START
) start_rstats(1);
948 if (strcmp(service
, "sched") == 0) {
949 if (action
& A_STOP
) stop_sched();
950 if (action
& A_START
) start_sched();
955 if (strcmp(service
, "smbd") == 0) {
956 if (action
& A_STOP
) stop_smbd();
957 if (action
& A_START
) start_smbd();
961 if (strcmp(service
, "test1") == 0) {
962 if (action
& A_STOP
) stop_test_1();
963 if (action
& A_START
) start_test_1();
968 if (strncmp(service
, "vpnclient", 9) == 0) {
969 if (action
& A_STOP
) stop_vpnclient(atoi(&service
[9]));
970 if (action
& A_START
) start_vpnclient(atoi(&service
[9]));
974 if (strncmp(service
, "vpnserver", 9) == 0) {
975 if (action
& A_STOP
) stop_vpnserver(atoi(&service
[9]));
976 if (action
& A_START
) start_vpnserver(atoi(&service
[9]));
984 // some functions check action_service and must be cleared at end -- zzz
985 nvram_set("action_service", "");
988 static void do_service(const char *name
, const char *action
, int user
)
994 while (!nvram_match("action_service", "")) {
999 else if (--n
< 0) break;
1003 snprintf(s
, sizeof(s
), "%s-%s", name
, action
);
1004 nvram_set("action_service", s
);
1008 while (nvram_match("action_service", s
)) {
1013 else if (--n
< 0) break;
1018 int service_main(int argc
, char *argv
[])
1020 if (argc
!= 3) usage_exit(argv
[0], "<service> <action>");
1021 do_service(argv
[1], argv
[2], 1);
1022 printf("\nDone.\n");
1026 void start_service(const char *name
)
1028 do_service(name
, "start", 0);
1031 void stop_service(const char *name
)
1033 do_service(name
, "stop", 0);