dnsmasq: fix DNS/hostname resolution on LAN bridges with DHCP disabled
[tomato.git] / release / src / router / rc / services.c
blob47a544c043664e3201e299d5d1910f482ee58549
1 /*
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
22 All Rights Reserved.
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
36 #include "rc.h"
38 #include <arpa/inet.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <errno.h>
43 // !!TB
44 #include <sys/mount.h>
45 #include <mntent.h>
46 #include <dirent.h>
48 // Pop an alarm to recheck pids in 500 msec.
49 static const struct itimerval pop_tv = { {0,0}, {0, 500 * 1000} };
51 // Pop an alarm to reap zombies.
52 static const struct itimerval zombie_tv = { {0,0}, {307, 0} };
54 // -----------------------------------------------------------------------------
56 static const char dmhosts[] = "/etc/dnsmasq/hosts";
57 static const char dmdhcp[] = "/etc/dnsmasq/dhcp";
58 static const char dmresolv[] = "/etc/resolv.dnsmasq";
60 static pid_t pid_dnsmasq = -1;
62 static int is_wet(int idx, int unit, int subunit, void *param)
64 return nvram_match(wl_nvname("mode", unit, subunit), "wet");
67 void start_dnsmasq()
69 FILE *f;
70 const char *nv;
71 char buf[512];
72 char lan[24];
73 const char *router_ip;
74 char sdhcp_lease[32];
75 char *e;
76 int n;
77 char *mac, *ip, *name;
78 char *p;
79 int ipn;
80 char ipbuf[32];
81 FILE *hf, *df;
82 int dhcp_start;
83 int dhcp_count;
84 int dhcp_lease;
85 int do_dhcpd;
86 int do_dns;
87 int do_dhcpd_hosts;
89 TRACE_PT("begin\n");
91 if (getpid() != 1) {
92 start_service("dnsmasq");
93 return;
96 stop_dnsmasq();
98 if (foreach_wif(1, NULL, is_wet)) return;
100 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
102 router_ip = nvram_safe_get("lan_ipaddr");
104 fprintf(f,
105 "pid-file=/var/run/dnsmasq.pid\n");
106 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
107 if (*nv) fprintf(f, "domain=%s\n", nv);
110 // dns
111 const dns_list_t *dns = get_dns(); // this always points to a static buffer
113 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
114 else n = 4096;
115 fprintf(f,
116 "resolv-file=%s\n" // the real stuff is here
117 "addn-hosts=%s\n" // directory with additional hosts files
118 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
119 "expand-hosts\n" // expand hostnames in hosts file
120 "min-port=%u\n", // min port used for random src port
121 dmresolv, dmhosts, dmdhcp, n);
122 do_dns = nvram_match("dhcpd_dmdns", "1");
124 // DNS rebinding protection, will discard upstream RFC1918 responses
125 if (nvram_get_int("dns_norebind")) {
126 fprintf(f,
127 "stop-dns-rebind\n"
128 "rebind-localhost-ok\n");
129 // allow RFC1918 responses for server domain
130 switch (get_wan_proto()) {
131 case WP_PPTP:
132 nv = nvram_get("pptp_server_ip");
133 break;
134 case WP_L2TP:
135 nv = nvram_get("l2tp_server_ip");
136 break;
137 default:
138 nv = NULL;
139 break;
141 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
144 for (n = 0 ; n < dns->count; ++n) {
145 if (dns->dns[n].port != 53) {
146 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
150 if (nvram_get_int("dhcpd_static_only")) {
151 fprintf(f, "dhcp-ignore=tag:!known\n");
154 // dhcp
155 do_dhcpd_hosts=0;
156 char lanN_proto[] = "lanXX_proto";
157 char lanN_ifname[] = "lanXX_ifname";
158 char lanN_ipaddr[] = "lanXX_ipaddr";
159 char lanN_netmask[] = "lanXX_netmask";
160 char dhcpdN_startip[] = "dhcpdXX_startip";
161 char dhcpdN_endip[] = "dhcpdXX_endip";
162 char dhcpN_start[] = "dhcpXX_start";
163 char dhcpN_num[] = "dhcpXX_num";
164 char dhcpN_lease[] = "dhcpXX_lease";
165 char br;
166 for(br=0 ; br<=3 ; br++) {
167 char bridge[2] = "0";
168 if (br!=0)
169 bridge[0]+=br;
170 else
171 strcpy(bridge, "");
173 sprintf(lanN_proto, "lan%s_proto", bridge);
174 sprintf(lanN_ifname, "lan%s_ifname", bridge);
175 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
176 do_dhcpd = nvram_match(lanN_proto, "dhcp");
177 if (do_dhcpd) {
178 do_dhcpd_hosts++;
180 router_ip = nvram_safe_get(lanN_ipaddr);
181 strlcpy(lan, router_ip, sizeof(lan));
182 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
184 fprintf(f,
185 "interface=%s\n",
186 nvram_safe_get(lanN_ifname));
188 sprintf(dhcpN_lease, "dhcp%s_lease", bridge);
189 dhcp_lease = nvram_get_int(dhcpN_lease);
191 if (dhcp_lease <= 0) dhcp_lease = 1440;
193 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
194 if (n < 0) strcpy(sdhcp_lease, "infinite");
195 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
197 if (!do_dns) {
198 // if not using dnsmasq for dns
200 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
201 // no DNS might be temporary. use a low lease time to force clients to update.
202 dhcp_lease = 2;
203 strcpy(sdhcp_lease, "2m");
204 do_dns = 1;
206 else {
207 // pass the dns directly
208 buf[0] = 0;
209 for (n = 0 ; n < dns->count; ++n) {
210 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
211 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
214 fprintf(f, "dhcp-option=%s,6%s\n", nvram_safe_get(lanN_ifname), buf);
218 sprintf(dhcpdN_startip, "dhcpd%s_startip", bridge);
219 sprintf(dhcpdN_endip, "dhcpd%s_endip", bridge);
220 sprintf(lanN_netmask, "lan%s_netmask", bridge);
222 if ((p = nvram_get(dhcpdN_startip)) && (*p) && (e = nvram_get(dhcpdN_endip)) && (*e)) {
223 fprintf(f, "dhcp-range=%s,%s,%s,%s,%dm\n", nvram_safe_get(lanN_ifname), p, e, nvram_safe_get(lanN_netmask), dhcp_lease);
225 else {
226 // for compatibility
227 sprintf(dhcpN_start, "dhcp%s_start", bridge);
228 sprintf(dhcpN_num, "dhcp%s_num", bridge);
229 sprintf(lanN_netmask, "lan%s_netmask", bridge);
230 dhcp_start = nvram_get_int(dhcpN_start);
231 dhcp_count = nvram_get_int(dhcpN_num);
232 fprintf(f, "dhcp-range=%s,%s%d,%s%d,%s,%dm\n",
233 nvram_safe_get(lanN_ifname), lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get(lanN_netmask), dhcp_lease);
236 nv = nvram_safe_get(lanN_ipaddr);
237 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
238 p = nvram_safe_get("lan_gateway");
239 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
242 fprintf(f,
243 "dhcp-option=%s,3,%s\n", // gateway
244 nvram_safe_get(lanN_ifname), nv);
246 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
247 fprintf(f, "dhcp-option=%s,44,%s\n", nvram_safe_get(lanN_ifname), nv);
249 #ifdef TCONFIG_SAMBASRV
250 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
251 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
252 // Samba will serve as a WINS server
253 fprintf(f, "dhcp-option=%s,44,0.0.0.0\n", nvram_safe_get(lanN_ifname));
256 #endif
257 } else {
258 if (strcmp(nvram_safe_get(lanN_ifname),"")!=0) {
259 fprintf(f, "interface=%s\n", nvram_safe_get(lanN_ifname));
260 fprintf(f, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname));
263 // write static lease entries & create hosts file
265 mkdir_if_none(dmhosts);
266 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
267 if ((hf = fopen(buf, "w")) != NULL) {
268 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
269 fprintf(hf, "%s %s\n", router_ip, nv);
270 #ifdef TCONFIG_SAMBASRV
271 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
272 fprintf(hf, "%s %s\n", router_ip, nv);
273 #endif
274 p = (char *)get_wanip();
275 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
276 p = "127.0.0.1";
277 fprintf(hf, "%s wan-ip\n", p);
278 if (nv && (*nv))
279 fprintf(hf, "%s %s-wan\n", p, nv);
282 mkdir_if_none(dmdhcp);
283 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
284 df = fopen(buf, "w");
286 // PREVIOUS/OLD FORMAT:
287 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
288 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
289 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
291 // NEW FORMAT (+static ARP binding after hostname):
292 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 55 w/ delim
293 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
294 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 108 w/ delim
296 p = nvram_safe_get("dhcpd_static");
297 while ((e = strchr(p, '>')) != NULL) {
298 n = (e - p);
299 if (n > 107) {
300 p = e + 1;
301 continue;
304 strncpy(buf, p, n);
305 buf[n] = 0;
306 p = e + 1;
308 if ((e = strchr(buf, '<')) == NULL) continue;
309 *e = 0;
310 mac = buf;
312 ip = e + 1;
313 if ((e = strchr(ip, '<')) == NULL) continue;
314 *e = 0;
315 if (strchr(ip, '.') == NULL) {
316 ipn = atoi(ip);
317 if ((ipn <= 0) || (ipn > 255)) continue;
318 sprintf(ipbuf, "%s%d", lan, ipn);
319 ip = ipbuf;
321 else {
322 if (inet_addr(ip) == INADDR_NONE) continue;
325 name = e + 1;
327 if ((e = strchr(name, '<')) != NULL) {
328 *e = 0;
331 if ((hf) && (*name != 0)) {
332 fprintf(hf, "%s %s\n", ip, name);
335 if ((do_dhcpd_hosts > 0) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
336 if (nvram_get_int("dhcpd_slt") == 0) {
337 fprintf(f, "dhcp-host=%s,%s\n", mac, ip);
338 } else {
339 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
344 if (df) fclose(df);
345 if (hf) fclose(hf);
347 n = nvram_get_int("dhcpd_lmax");
348 fprintf(f,
349 "dhcp-lease-max=%d\n",
350 (n > 0) ? n : 255);
351 if (nvram_get_int("dhcpd_auth") >= 0) {
352 fprintf(f, "dhcp-authoritative\n");
357 #ifdef TCONFIG_OPENVPN
358 write_vpn_dnsmasq_config(f);
359 #endif
361 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
363 fappend(f, "/etc/dnsmasq.custom");
367 fclose(f);
369 if (do_dns) {
370 unlink("/etc/resolv.conf");
371 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
374 TRACE_PT("run dnsmasq\n");
376 // Default to some values we like, but allow the user to override them.
377 eval("dnsmasq", "-c", "1500", "--log-async");
379 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
380 pid_dnsmasq = -2;
383 TRACE_PT("end\n");
386 void stop_dnsmasq(void)
388 TRACE_PT("begin\n");
390 if (getpid() != 1) {
391 stop_service("dnsmasq");
392 return;
395 pid_dnsmasq = -1;
397 unlink("/etc/resolv.conf");
398 symlink(dmresolv, "/etc/resolv.conf");
400 killall_tk("dnsmasq");
402 TRACE_PT("end\n");
405 void clear_resolv(void)
407 f_write(dmresolv, NULL, 0, 0, 0); // blank
410 #ifdef TCONFIG_IPV6
411 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
413 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
414 struct in6_addr addr;
415 int cnt = 0;
417 foreach(p, dns, next) {
418 // verify that this is a valid IPv6 address
419 if (inet_pton(AF_INET6, p, &addr) == 1) {
420 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
421 ++cnt;
425 return cnt;
427 #endif
429 void dns_to_resolv(void)
431 FILE *f;
432 const dns_list_t *dns;
433 int i;
434 mode_t m;
436 m = umask(022); // 077 from pppoecd
437 if ((f = fopen(dmresolv, "w")) != NULL) {
438 // Check for VPN DNS entries
439 if (!write_vpn_resolv(f)) {
440 #ifdef TCONFIG_IPV6
441 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
442 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
443 #endif
444 dns = get_dns(); // static buffer
445 if (dns->count == 0) {
446 // Put a pseudo DNS IP to trigger Connect On Demand
447 if (nvram_match("ppp_demand", "1")) {
448 switch (get_wan_proto()) {
449 case WP_PPPOE:
450 case WP_PPP3G:
451 case WP_PPTP:
452 case WP_L2TP:
453 fprintf(f, "nameserver 1.1.1.1\n");
454 break;
458 else {
459 for (i = 0; i < dns->count; i++) {
460 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
461 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
466 fclose(f);
468 umask(m);
471 // -----------------------------------------------------------------------------
473 void start_httpd(void)
475 if (getpid() != 1) {
476 start_service("httpd");
477 return;
480 stop_httpd();
481 chdir("/www");
482 eval("httpd");
483 chdir("/");
486 void stop_httpd(void)
488 if (getpid() != 1) {
489 stop_service("httpd");
490 return;
493 killall_tk("httpd");
496 // -----------------------------------------------------------------------------
497 #ifdef TCONFIG_IPV6
499 static void add_ip6_lanaddr(void)
501 char ip[INET6_ADDRSTRLEN + 4];
502 const char *p;
504 p = ipv6_router_address(NULL);
505 if (*p) {
506 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
507 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
511 void start_ipv6_tunnel(void)
513 char ip[INET6_ADDRSTRLEN + 4];
514 struct in_addr addr4;
515 struct in6_addr addr;
516 const char *wanip, *mtu, *tun_dev;
517 int service;
519 service = get_ipv6_service();
520 tun_dev = get_wan6face();
521 wanip = get_wanip();
522 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
523 modprobe("sit");
525 if (service == IPV6_ANYCAST_6TO4)
526 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
527 else
528 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
529 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
530 "remote", ip,
531 "local", (char *)wanip,
532 "ttl", nvram_safe_get("ipv6_tun_ttl"));
534 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
535 nvram_set("ipv6_ifname", (char *)tun_dev);
537 if (service == IPV6_ANYCAST_6TO4) {
538 add_ip6_lanaddr();
539 addr4.s_addr = 0;
540 memset(&addr, 0, sizeof(addr));
541 inet_aton(wanip, &addr4);
542 addr.s6_addr16[0] = htons(0x2002);
543 ipv6_mapaddr4(&addr, 16, &addr4, 0);
544 addr.s6_addr16[7] = htons(0x0001);
545 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
546 strncat(ip, "/16", sizeof(ip));
548 else {
549 snprintf(ip, sizeof(ip), "%s/%d",
550 nvram_safe_get("ipv6_tun_addr"),
551 nvram_get_int("ipv6_tun_addrlen") ? : 64);
553 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
554 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
556 // (re)start radvd
557 if (service == IPV6_ANYCAST_6TO4)
558 start_radvd();
561 void stop_ipv6_tunnel(void)
563 eval("ip", "tunnel", "del", (char *)get_wan6face());
564 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
565 // get rid of old IPv6 address from lan iface
566 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
568 modprobe_r("sit");
571 static pid_t pid_radvd = -1;
573 void start_radvd(void)
575 FILE *f;
576 char *prefix, *ip, *mtu;
577 int do_dns, do_6to4;
578 char *argv[] = { "radvd", NULL, NULL, NULL };
579 int pid, argc, service, cnt;
581 if (getpid() != 1) {
582 start_service("radvd");
583 return;
586 stop_radvd();
588 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
589 service = get_ipv6_service();
590 do_6to4 = (service == IPV6_ANYCAST_6TO4);
591 mtu = NULL;
593 switch (service) {
594 case IPV6_NATIVE_DHCP:
595 prefix = "::";
596 break;
597 case IPV6_ANYCAST_6TO4:
598 case IPV6_6IN4:
599 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
600 // fall through
601 default:
602 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
603 break;
605 if (!(*prefix)) prefix = "::";
607 // Create radvd.conf
608 if ((f = fopen("/etc/radvd.conf", "w")) == NULL) return;
610 ip = (char *)ipv6_router_address(NULL);
611 do_dns = (*ip) && nvram_match("dhcpd_dmdns", "1");
613 fprintf(f,
614 "interface %s\n"
615 "{\n"
616 " IgnoreIfMissing on;\n"
617 " AdvSendAdvert on;\n"
618 " MaxRtrAdvInterval 60;\n"
619 " AdvHomeAgentFlag off;\n"
620 " AdvManagedFlag off;\n"
621 "%s%s%s"
622 " prefix %s/64 \n"
623 " {\n"
624 " AdvOnLink on;\n"
625 " AdvAutonomous on;\n"
626 "%s"
627 "%s%s%s"
628 " };\n",
629 nvram_safe_get("lan_ifname"),
630 mtu ? " AdvLinkMTU " : "", mtu ? : "", mtu ? ";\n" : "",
631 prefix,
632 do_6to4 ? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
633 do_6to4 ? " Base6to4Interface " : "",
634 do_6to4 ? get_wanface() : "",
635 do_6to4 ? ";\n" : "");
637 if (do_dns) {
638 fprintf(f, " RDNSS %s {};\n", ip);
640 else {
641 cnt = write_ipv6_dns_servers(f, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
642 if (cnt == 0 || nvram_get_int("dns_addget"))
643 cnt += write_ipv6_dns_servers(f, (cnt) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
644 if (cnt) fprintf(f, "{};\n");
647 fprintf(f,
648 "};\n"); // close "interface" section
649 fclose(f);
651 // Start radvd
652 argc = 1;
653 if (nvram_get_int("debug_ipv6")) {
654 argv[argc++] = "-d";
655 argv[argc++] = "10";
657 argv[argc] = NULL;
658 _eval(argv, NULL, 0, &pid);
660 if (!nvram_contains_word("debug_norestart", "radvd")) {
661 pid_radvd = -2;
666 void stop_radvd(void)
668 if (getpid() != 1) {
669 stop_service("radvd");
670 return;
673 pid_radvd = -1;
674 killall_tk("radvd");
677 void start_ipv6(void)
679 int service;
681 service = get_ipv6_service();
682 enable_ip_forward();
684 // Check if turned on
685 switch (service) {
686 case IPV6_NATIVE:
687 case IPV6_6IN4:
688 case IPV6_MANUAL:
689 add_ip6_lanaddr();
690 break;
691 case IPV6_NATIVE_DHCP:
692 case IPV6_ANYCAST_6TO4:
693 nvram_set("ipv6_rtr_addr", "");
694 nvram_set("ipv6_prefix", "");
695 break;
698 if (service != IPV6_DISABLED) {
699 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
700 accept_ra(nvram_safe_get("lan_ifname"));
704 void stop_ipv6(void)
706 stop_ipv6_tunnel();
707 stop_dhcp6c();
708 eval("ip", "-6", "addr", "flush", "scope", "global");
711 #endif
713 // -----------------------------------------------------------------------------
715 void start_upnp(void)
717 if (getpid() != 1) {
718 start_service("upnp");
719 return;
722 if (get_wan_proto() == WP_DISABLED) return;
724 int enable;
725 FILE *f;
726 int upnp_port;
728 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
729 mkdir("/etc/upnp", 0777);
730 if (f_exists("/etc/upnp/config.alt")) {
731 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
733 else {
734 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
735 upnp_port = nvram_get_int("upnp_port");
736 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
739 fprintf(f,
740 "ext_ifname=%s\n"
741 "port=%d\n"
742 "enable_upnp=%s\n"
743 "enable_natpmp=%s\n"
744 "secure_mode=%s\n"
745 "upnp_forward_chain=upnp\n"
746 "upnp_nat_chain=upnp\n"
747 "notify_interval=%d\n"
748 "system_uptime=yes\n"
749 "\n"
751 get_wanface(),
752 upnp_port,
753 (enable & 1) ? "yes" : "no", // upnp enable
754 (enable & 2) ? "yes" : "no", // natpmp enable
755 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
756 nvram_get_int("upnp_ssdp_interval")
759 if (nvram_get_int("upnp_clean")) {
760 int interval = nvram_get_int("upnp_clean_interval");
761 if (interval < 60) interval = 60;
762 fprintf(f,
763 "clean_ruleset_interval=%d\n"
764 "clean_ruleset_threshold=%d\n",
765 interval,
766 nvram_get_int("upnp_clean_threshold")
769 else
770 fprintf(f,"clean_ruleset_interval=0\n");
772 if (nvram_match("upnp_mnp", "1")) {
773 int https = nvram_get_int("https_enable");
774 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
775 https ? "s" : "", nvram_safe_get("lan_ipaddr"),
776 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
778 else {
779 // Empty parameters are not included into XML service description
780 fprintf(f, "presentation_url=\n");
783 char uuid[45];
784 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
785 fprintf(f, "uuid=%s\n", uuid);
787 char lanN_ipaddr[] = "lanXX_ipaddr";
788 char lanN_netmask[] = "lanXX_netmask";
789 char upnp_lanN[] = "upnp_lanXX";
790 char br;
792 for(br=0 ; br<4 ; br++) {
793 char bridge[2] = "0";
794 if (br!=0)
795 bridge[0]+=br;
796 else
797 strcpy(bridge, "");
799 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
800 sprintf(lanN_netmask, "lan%s_netmask", bridge);
801 sprintf(upnp_lanN, "upnp_lan%s", bridge);
803 char *lanip = nvram_safe_get(lanN_ipaddr);
804 char *lanmask = nvram_safe_get(lanN_netmask);
805 char *lanlisten = nvram_safe_get(upnp_lanN);
806 if((strcmp(lanlisten,"1")==0) && (strcmp(lanip,"")!=0) && (strcmp(lanip,"0.0.0.0")!=0)) {
807 fprintf(f,
808 "listening_ip=%s/%s\n",
809 lanip, lanmask);
810 int ports[4];
811 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
812 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
813 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
814 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
815 fprintf(f,
816 "allow %d-%d %s/%s %d-%d\n",
817 ports[0], ports[1],
818 lanip, lanmask,
819 ports[2], ports[3]
822 else {
823 // by default allow only redirection of ports above 1024
824 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
829 fappend(f, "/etc/upnp/config.custom");
830 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
831 fclose(f);
833 xstart("miniupnpd", "-f", "/etc/upnp/config");
839 void stop_upnp(void)
841 if (getpid() != 1) {
842 stop_service("upnp");
843 return;
846 killall_tk("miniupnpd");
849 // -----------------------------------------------------------------------------
851 static pid_t pid_crond = -1;
853 void start_cron(void)
855 stop_cron();
857 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
858 if (!nvram_contains_word("debug_norestart", "crond")) {
859 pid_crond = -2;
863 void stop_cron(void)
865 pid_crond = -1;
866 killall_tk("crond");
869 // -----------------------------------------------------------------------------
870 #ifdef LINUX26
872 static pid_t pid_hotplug2 = -1;
874 void start_hotplug2()
876 stop_hotplug2();
878 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
879 xstart("hotplug2", "--persistent", "--no-coldplug");
880 // FIXME: Don't remember exactly why I put "sleep" here -
881 // but it was not for a race with check_services()... - TB
882 sleep(1);
884 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
885 pid_hotplug2 = -2;
889 void stop_hotplug2(void)
891 pid_hotplug2 = -1;
892 killall_tk("hotplug2");
895 #endif /* LINUX26 */
896 // -----------------------------------------------------------------------------
898 // Written by Sparq in 2002/07/16
899 void start_zebra(void)
901 #ifdef TCONFIG_ZEBRA
902 if (getpid() != 1) {
903 start_service("zebra");
904 return;
907 FILE *fp;
909 char *lan_tx = nvram_safe_get("dr_lan_tx");
910 char *lan_rx = nvram_safe_get("dr_lan_rx");
911 char *lan1_tx = nvram_safe_get("dr_lan1_tx");
912 char *lan1_rx = nvram_safe_get("dr_lan1_rx");
913 char *lan2_tx = nvram_safe_get("dr_lan2_tx");
914 char *lan2_rx = nvram_safe_get("dr_lan2_rx");
915 char *lan3_tx = nvram_safe_get("dr_lan3_tx");
916 char *lan3_rx = nvram_safe_get("dr_lan3_rx");
917 char *wan_tx = nvram_safe_get("dr_wan_tx");
918 char *wan_rx = nvram_safe_get("dr_wan_rx");
920 if ((*lan_tx == '0') && (*lan_rx == '0') &&
921 (*lan1_tx == '0') && (*lan1_rx == '0') &&
922 (*lan2_tx == '0') && (*lan2_rx == '0') &&
923 (*lan3_tx == '0') && (*lan3_rx == '0') &&
924 (*wan_tx == '0') && (*wan_rx == '0')) {
925 return;
928 // empty
929 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
930 fclose(fp);
934 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
935 char *lan_ifname = nvram_safe_get("lan_ifname");
936 char *lan1_ifname = nvram_safe_get("lan1_ifname");
937 char *lan2_ifname = nvram_safe_get("lan2_ifname");
938 char *lan3_ifname = nvram_safe_get("lan3_ifname");
939 char *wan_ifname = nvram_safe_get("wan_ifname");
941 fprintf(fp, "router rip\n");
942 if(strcmp(lan_ifname,"")!=0)
943 fprintf(fp, "network %s\n", lan_ifname);
944 if(strcmp(lan1_ifname,"")!=0)
945 fprintf(fp, "network %s\n", lan1_ifname);
946 if(strcmp(lan2_ifname,"")!=0)
947 fprintf(fp, "network %s\n", lan2_ifname);
948 if(strcmp(lan3_ifname,"")!=0)
949 fprintf(fp, "network %s\n", lan3_ifname);
950 fprintf(fp, "network %s\n", wan_ifname);
951 fprintf(fp, "redistribute connected\n");
952 //fprintf(fp, "redistribute static\n");
954 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
955 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
957 if(strcmp(lan_ifname,"")!=0) {
958 fprintf(fp, "interface %s\n", lan_ifname);
959 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
960 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
962 if(strcmp(lan1_ifname,"")!=0) {
963 fprintf(fp, "interface %s\n", lan1_ifname);
964 if (*lan1_tx != '0') fprintf(fp, "ip rip send version %s\n", lan1_tx);
965 if (*lan1_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan1_rx);
967 if(strcmp(lan2_ifname,"")!=0) {
968 fprintf(fp, "interface %s\n", lan2_ifname);
969 if (*lan2_tx != '0') fprintf(fp, "ip rip send version %s\n", lan2_tx);
970 if (*lan2_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan2_rx);
972 if(strcmp(lan3_ifname,"")!=0) {
973 fprintf(fp, "interface %s\n", lan3_ifname);
974 if (*lan3_tx != '0') fprintf(fp, "ip rip send version %s\n", lan3_tx);
975 if (*lan3_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan3_rx);
977 fprintf(fp, "interface %s\n", wan_ifname);
978 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
979 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
981 fprintf(fp, "router rip\n");
982 if(strcmp(lan_ifname,"")!=0) {
983 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
984 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
986 if(strcmp(lan1_ifname,"")!=0) {
987 if (*lan1_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan1_ifname);
988 if (*lan1_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan1_ifname);
990 if(strcmp(lan2_ifname,"")!=0) {
991 if (*lan2_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan2_ifname);
992 if (*lan2_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan2_ifname);
994 if(strcmp(lan3_ifname,"")!=0) {
995 if (*lan3_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan3_ifname);
996 if (*lan3_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan3_ifname);
998 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
999 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
1000 fprintf(fp, "access-list private deny any\n");
1002 //fprintf(fp, "debug rip events\n");
1003 //fprintf(fp, "log file /etc/ripd.log\n");
1004 fclose(fp);
1007 xstart("zebra", "-d");
1008 xstart("ripd", "-d");
1009 #endif
1012 void stop_zebra(void)
1014 #ifdef TCONFIG_ZEBRA
1015 if (getpid() != 1) {
1016 stop_service("zebra");
1017 return;
1020 killall("zebra", SIGTERM);
1021 killall("ripd", SIGTERM);
1023 unlink("/etc/zebra.conf");
1024 unlink("/etc/ripd.conf");
1025 #endif
1028 // -----------------------------------------------------------------------------
1030 void start_syslog(void)
1032 char *argv[16];
1033 int argc;
1034 char *nv;
1035 char *b_opt = "";
1036 char rem[256];
1037 int n;
1038 char s[64];
1039 char cfg[256];
1040 char *rot_siz = "50";
1041 char *rot_keep = "1";
1042 char *log_file_path;
1044 argv[0] = "syslogd";
1045 argc = 1;
1047 if (nvram_match("log_remote", "1")) {
1048 nv = nvram_safe_get("log_remoteip");
1049 if (*nv) {
1050 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
1051 argv[argc++] = "-R";
1052 argv[argc++] = rem;
1056 if (nvram_match("log_file", "1")) {
1057 argv[argc++] = "-L";
1059 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1060 rot_siz = nvram_safe_get("log_file_size");
1062 if (nvram_get_int("log_file_size") > 0) {
1063 rot_keep = nvram_safe_get("log_file_keep");
1066 // log to custom path - shibby
1067 if (nvram_match("log_file_custom", "1")) {
1068 log_file_path = nvram_safe_get("log_file_path");
1069 argv[argc++] = roz_siz;
1070 argv[argc++] = "-O";
1071 argv[argc++] = log_file_path;
1072 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1073 remove("/var/log/messages");
1074 symlink(log_file_path, "/var/log/messages");
1077 else
1079 /* Read options: rotate_size(kb) num_backups logfilename.
1080 * Ignore these settings and use defaults if the logfile cannot be written to.
1082 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
1083 if ((nv = strchr(cfg, '\n')))
1084 *nv = 0;
1086 if ((nv = strtok(cfg, " \t"))) {
1087 if (isdigit(*nv))
1088 rot_siz = nv;
1091 if ((nv = strtok(NULL, " \t")))
1092 b_opt = nv;
1094 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
1095 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
1096 argv[argc++] = "-O";
1097 argv[argc++] = nv;
1099 else {
1100 rot_siz = "50";
1101 b_opt = "";
1106 if (nvram_match("log_file_custom", "0")) {
1107 argv[argc++] = "-s";
1108 argv[argc++] = rot_siz;
1109 remove("/var/log/messages");
1112 if (isdigit(*b_opt)) {
1113 argv[argc++] = "-b";
1114 argv[argc++] = b_opt;
1115 } else
1116 if (nvram_get_int("log_file_size") > 0) {
1117 argv[argc++] = "-b";
1118 argv[argc++] = rot_keep;
1122 if (argc > 1) {
1123 argv[argc] = NULL;
1124 _eval(argv, NULL, 0, NULL);
1126 argv[0] = "klogd";
1127 argv[1] = NULL;
1128 _eval(argv, NULL, 0, NULL);
1130 // used to be available in syslogd -m
1131 n = nvram_get_int("log_mark");
1132 if (n > 0) {
1133 // n is in minutes
1134 if (n < 60)
1135 sprintf(rem, "*/%d * * * *", n);
1136 else if (n < 60 * 24)
1137 sprintf(rem, "0 */%d * * *", n / 60);
1138 else
1139 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1140 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1141 eval("cru", "a", "syslogdmark", s);
1143 else {
1144 eval("cru", "d", "syslogdmark");
1149 void stop_syslog(void)
1151 killall("klogd", SIGTERM);
1152 killall("syslogd", SIGTERM);
1155 // -----------------------------------------------------------------------------
1157 static pid_t pid_igmp = -1;
1159 void start_igmp_proxy(void)
1161 FILE *fp;
1163 pid_igmp = -1;
1164 if (nvram_match("multicast_pass", "1")) {
1165 if (get_wan_proto() == WP_DISABLED)
1166 return;
1168 if (f_exists("/etc/igmp.alt")) {
1169 eval("igmpproxy", "/etc/igmp.alt");
1171 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1172 fprintf(fp,
1173 "quickleave\n"
1174 "phyint %s upstream\n"
1175 "\taltnet %s\n",
1176 // "phyint %s downstream ratelimit 0\n",
1177 get_wanface(),
1178 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1179 // nvram_safe_get("lan_ifname"));
1181 char lanN_ifname[] = "lanXX_ifname";
1182 char multicast_lanN[] = "multicast_lanXX";
1183 char br;
1185 for(br=0 ; br<4 ; br++) {
1186 char bridge[2] = "0";
1187 if (br!=0)
1188 bridge[0]+=br;
1189 else
1190 strcpy(bridge, "");
1192 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1193 sprintf(multicast_lanN, "multicast_lan%s", bridge);
1195 if((strcmp(nvram_safe_get(multicast_lanN),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname),"")!=0)) {
1196 fprintf(fp,
1197 "phyint %s downstream ratelimit 0\n",
1198 nvram_safe_get(lanN_ifname));
1201 fclose(fp);
1202 eval("igmpproxy", "/etc/igmp.conf");
1204 else {
1205 return;
1207 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1208 pid_igmp = -2;
1213 void stop_igmp_proxy(void)
1215 pid_igmp = -1;
1216 killall_tk("igmpproxy");
1219 #ifdef TCONFIG_NOCAT
1221 static pid_t pid_splashd = -1;
1222 void start_splashd(void)
1224 pid_splashd = -1;
1225 start_nocat();
1226 if (!nvram_contains_word("debug_norestart", "splashd")) {
1227 pid_splashd = -2;
1231 void stop_splashd(void)
1233 pid_splashd = -1;
1234 stop_nocat();
1235 start_wan(BOOT);
1237 #endif
1239 // -----------------------------------------------------------------------------
1241 void set_tz(void)
1243 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1246 void start_ntpc(void)
1248 set_tz();
1250 stop_ntpc();
1252 if (nvram_get_int("ntp_updates") >= 0) {
1253 xstart("ntpsync", "--init");
1257 void stop_ntpc(void)
1259 killall("ntpsync", SIGTERM);
1262 // -----------------------------------------------------------------------------
1264 static void stop_rstats(void)
1266 int n, m;
1267 int pid;
1268 int pidz;
1269 int ppidz;
1270 int w = 0;
1272 n = 60;
1273 m = 15;
1274 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1275 w = 1;
1276 pidz = pidof("gzip");
1277 if (pidz < 1) pidz = pidof("cp");
1278 ppidz = ppid(ppid(pidz));
1279 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1280 syslog(LOG_DEBUG, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1281 --m;
1282 } else {
1283 kill(pid, SIGTERM);
1285 sleep(1);
1287 if ((w == 1) && (n > 0))
1288 syslog(LOG_DEBUG, "rstats stopped.\n");
1291 static void start_rstats(int new)
1293 if (nvram_match("rstats_enable", "1")) {
1294 stop_rstats();
1295 if (new) {
1296 syslog(LOG_DEBUG, "starting rstats (new datafile).\n");
1297 xstart("rstats", "--new");
1298 } else {
1299 syslog(LOG_DEBUG, "starting rstats.\n");
1300 xstart("rstats");
1305 static void stop_cstats(void)
1307 int n, m;
1308 int pid;
1309 int pidz;
1310 int ppidz;
1311 int w = 0;
1313 n = 60;
1314 m = 15;
1315 while ((n-- > 0) && ((pid = pidof("cstats")) > 0)) {
1316 w = 1;
1317 pidz = pidof("gzip");
1318 if (pidz < 1) pidz = pidof("cp");
1319 ppidz = ppid(ppid(pidz));
1320 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1321 syslog(LOG_DEBUG, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1322 --m;
1323 } else {
1324 kill(pid, SIGTERM);
1326 sleep(1);
1328 if ((w == 1) && (n > 0))
1329 syslog(LOG_DEBUG, "cstats stopped.\n");
1332 static void start_cstats(int new)
1334 if (nvram_match("cstats_enable", "1")) {
1335 stop_cstats();
1336 if (new) {
1337 syslog(LOG_DEBUG, "starting cstats (new datafile).\n");
1338 xstart("cstats", "--new");
1339 } else {
1340 syslog(LOG_DEBUG, "starting cstats.\n");
1341 xstart("cstats");
1346 // -----------------------------------------------------------------------------
1348 // !!TB - FTP Server
1350 #ifdef TCONFIG_FTP
1351 static char *get_full_storage_path(char *val)
1353 static char buf[128];
1354 int len;
1356 if (val[0] == '/')
1357 len = sprintf(buf, "%s", val);
1358 else
1359 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1361 if (len > 1 && buf[len - 1] == '/')
1362 buf[len - 1] = 0;
1364 return buf;
1367 static char *nvram_storage_path(char *var)
1369 char *val = nvram_safe_get(var);
1370 return get_full_storage_path(val);
1373 char vsftpd_conf[] = "/etc/vsftpd.conf";
1374 char vsftpd_users[] = "/etc/vsftpd.users";
1375 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1377 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1379 static void start_ftpd(void)
1381 char tmp[256];
1382 FILE *fp, *f;
1383 char *buf;
1384 char *p, *q;
1385 int i;
1386 char *user, *pass, *rights, *root_dir;
1388 if (getpid() != 1) {
1389 start_service("ftpd");
1390 return;
1393 if (!nvram_get_int("ftp_enable")) return;
1395 mkdir_if_none(vsftpd_users);
1396 mkdir_if_none("/var/run/vsftpd");
1398 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1399 return;
1401 if (nvram_get_int("ftp_super"))
1403 /* rights */
1404 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1405 if ((f = fopen(tmp, "w")))
1407 fprintf(f,
1408 "dirlist_enable=yes\n"
1409 "write_enable=yes\n"
1410 "download_enable=yes\n");
1411 fclose(f);
1415 #ifdef TCONFIG_SAMBASRV
1416 if (nvram_match("smbd_cset", "utf8"))
1417 fprintf(fp, "utf8=yes\n");
1418 #endif
1420 if (nvram_invmatch("ftp_anonymous", "0"))
1422 fprintf(fp,
1423 "anon_allow_writable_root=yes\n"
1424 "anon_world_readable_only=no\n"
1425 "anon_umask=022\n");
1427 /* rights */
1428 sprintf(tmp, "%s/ftp", vsftpd_users);
1429 if ((f = fopen(tmp, "w")))
1431 if (nvram_match("ftp_dirlist", "0"))
1432 fprintf(f, "dirlist_enable=yes\n");
1433 if (nvram_match("ftp_anonymous", "1") ||
1434 nvram_match("ftp_anonymous", "3"))
1435 fprintf(f, "write_enable=yes\n");
1436 if (nvram_match("ftp_anonymous", "1") ||
1437 nvram_match("ftp_anonymous", "2"))
1438 fprintf(f, "download_enable=yes\n");
1439 fclose(f);
1441 if (nvram_match("ftp_anonymous", "1") ||
1442 nvram_match("ftp_anonymous", "3"))
1443 fprintf(fp,
1444 "anon_upload_enable=yes\n"
1445 "anon_mkdir_write_enable=yes\n"
1446 "anon_other_write_enable=yes\n");
1447 } else {
1448 fprintf(fp, "anonymous_enable=no\n");
1451 fprintf(fp,
1452 "dirmessage_enable=yes\n"
1453 "download_enable=no\n"
1454 "dirlist_enable=no\n"
1455 "hide_ids=yes\n"
1456 "syslog_enable=yes\n"
1457 "local_enable=yes\n"
1458 "local_umask=022\n"
1459 "chmod_enable=no\n"
1460 "chroot_local_user=yes\n"
1461 "check_shell=no\n"
1462 "log_ftp_protocol=%s\n"
1463 "user_config_dir=%s\n"
1464 "passwd_file=%s\n"
1465 "listen%s=yes\n"
1466 "listen_port=%s\n"
1467 "background=yes\n"
1468 "isolate=no\n"
1469 "max_clients=%d\n"
1470 "max_per_ip=%d\n"
1471 "max_login_fails=1\n"
1472 "idle_session_timeout=%s\n"
1473 "use_sendfile=no\n"
1474 "anon_max_rate=%d\n"
1475 "local_max_rate=%d\n"
1476 "%s\n",
1477 nvram_get_int("log_ftp") ? "yes" : "no",
1478 vsftpd_users, vsftpd_passwd,
1479 #ifdef TCONFIG_IPV6
1480 ipv6_enabled() ? "_ipv6" : "",
1481 #else
1483 #endif
1484 nvram_get("ftp_port") ? : "21",
1485 nvram_get_int("ftp_max"),
1486 nvram_get_int("ftp_ipmax"),
1487 nvram_get("ftp_staytimeout") ? : "300",
1488 nvram_get_int("ftp_anonrate") * 1024,
1489 nvram_get_int("ftp_rate") * 1024,
1490 nvram_safe_get("ftp_custom"));
1492 fclose(fp);
1494 /* prepare passwd file and default users */
1495 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1496 return;
1498 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1499 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1501 fprintf(fp, /* anonymous, admin, nobody */
1502 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1503 "%s:%s:0:0:root:/:/sbin/nologin\n"
1504 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1505 nvram_storage_path("ftp_anonroot"), user,
1506 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1507 MOUNT_ROOT);
1509 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1512 username<password<rights[<root_dir>]
1513 rights:
1514 Read/Write
1515 Read Only
1516 View Only
1517 Private
1519 p = buf;
1520 while ((q = strsep(&p, ">")) != NULL) {
1521 i = vstrsep(q, "<", &user, &pass, &rights, &root_dir);
1522 if (i < 3 || i > 4) continue;
1523 if (!user || !pass) continue;
1525 if (i == 3 || !root_dir || !(*root_dir))
1526 root_dir = nvram_safe_get("ftp_pubroot");
1528 /* directory */
1529 if (strncmp(rights, "Private", 7) == 0)
1531 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1532 mkdir_if_none(tmp);
1534 else
1535 sprintf(tmp, "%s", get_full_storage_path(root_dir));
1537 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1538 user, crypt(pass, "$1$"), user, tmp);
1540 /* rights */
1541 sprintf(tmp, "%s/%s", vsftpd_users, user);
1542 if ((f = fopen(tmp, "w")))
1544 tmp[0] = 0;
1545 if (nvram_invmatch("ftp_dirlist", "1"))
1546 strcat(tmp, "dirlist_enable=yes\n");
1547 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1548 strcat(tmp, "download_enable=yes\n");
1549 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1550 strcat(tmp, "write_enable=yes\n");
1552 fputs(tmp, f);
1553 fclose(f);
1556 free(buf);
1559 fclose(fp);
1560 killall("vsftpd", SIGHUP);
1562 /* start vsftpd if it's not already running */
1563 if (pidof("vsftpd") <= 0)
1564 xstart("vsftpd");
1567 static void stop_ftpd(void)
1569 if (getpid() != 1) {
1570 stop_service("ftpd");
1571 return;
1574 killall_tk("vsftpd");
1575 unlink(vsftpd_passwd);
1576 unlink(vsftpd_conf);
1577 eval("rm", "-rf", vsftpd_users);
1579 #endif // TCONFIG_FTP
1581 // -----------------------------------------------------------------------------
1583 // !!TB - Samba
1585 #ifdef TCONFIG_SAMBASRV
1586 static void kill_samba(int sig)
1588 if (sig == SIGTERM) {
1589 killall_tk("smbd");
1590 killall_tk("nmbd");
1592 else {
1593 killall("smbd", sig);
1594 killall("nmbd", sig);
1598 static void start_samba(void)
1600 FILE *fp;
1601 DIR *dir = NULL;
1602 struct dirent *dp;
1603 char nlsmod[15];
1604 int mode;
1605 char *nv;
1607 if (getpid() != 1) {
1608 start_service("smbd");
1609 return;
1612 mode = nvram_get_int("smbd_enable");
1613 if (!mode || !nvram_invmatch("lan_hostname", ""))
1614 return;
1616 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1617 return;
1619 fprintf(fp, "[global]\n"
1620 " interfaces = %s\n"
1621 " bind interfaces only = yes\n"
1622 " workgroup = %s\n"
1623 " netbios name = %s\n"
1624 " server string = %s\n"
1625 " guest account = nobody\n"
1626 " security = user\n"
1627 " %s\n"
1628 " guest ok = %s\n"
1629 " guest only = no\n"
1630 " browseable = yes\n"
1631 " syslog only = yes\n"
1632 " timestamp logs = no\n"
1633 " syslog = 1\n"
1634 " encrypt passwords = yes\n"
1635 " preserve case = yes\n"
1636 " short preserve case = yes\n",
1637 nvram_safe_get("lan_ifname"),
1638 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1639 nvram_safe_get("lan_hostname"),
1640 nvram_get("router_name") ? : "Tomato",
1641 mode == 2 ? "" : "map to guest = Bad User",
1642 mode == 2 ? "no" : "yes" // guest ok
1645 if (nvram_get_int("smbd_wins")) {
1646 nv = nvram_safe_get("wan_wins");
1647 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1648 fprintf(fp, " wins support = yes\n");
1652 if (nvram_get_int("smbd_master")) {
1653 fprintf(fp,
1654 " domain master = yes\n"
1655 " local master = yes\n"
1656 " preferred master = yes\n"
1657 " os level = 65\n");
1660 nv = nvram_safe_get("smbd_cpage");
1661 if (*nv) {
1662 #ifndef TCONFIG_SAMBA3
1663 fprintf(fp, " client code page = %s\n", nv);
1664 #endif
1665 sprintf(nlsmod, "nls_cp%s", nv);
1667 nv = nvram_safe_get("smbd_nlsmod");
1668 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1669 modprobe_r(nv);
1671 modprobe(nlsmod);
1672 nvram_set("smbd_nlsmod", nlsmod);
1675 #ifndef TCONFIG_SAMBA3
1676 if (nvram_match("smbd_cset", "utf8"))
1677 fprintf(fp, " coding system = utf8\n");
1678 else if (nvram_invmatch("smbd_cset", ""))
1679 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1680 #endif
1682 nv = nvram_safe_get("smbd_custom");
1683 /* add socket options unless overriden by the user */
1684 if (strstr(nv, "socket options") == NULL) {
1685 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1687 fprintf(fp, "%s\n\n", nv);
1689 /* configure shares */
1691 char *buf;
1692 char *p, *q;
1693 char *name, *path, *comment, *writeable, *hidden;
1694 int cnt = 0;
1696 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1698 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1700 p = buf;
1701 while ((q = strsep(&p, ">")) != NULL) {
1702 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1703 if (!path || !name) continue;
1705 /* share name */
1706 fprintf(fp, "\n[%s]\n", name);
1708 /* path */
1709 fprintf(fp, " path = %s\n", path);
1711 /* access level */
1712 if (!strcmp(writeable, "1"))
1713 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1714 if (!strcmp(hidden, "1"))
1715 fprintf(fp, " browseable = no\n");
1717 /* comment */
1718 if (comment)
1719 fprintf(fp, " comment = %s\n", comment);
1721 cnt++;
1723 free(buf);
1726 /* Share every mountpoint below MOUNT_ROOT */
1727 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1728 while ((dp = readdir(dir))) {
1729 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1731 /* Only if is a directory and is mounted */
1732 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1733 continue;
1735 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1736 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1737 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1738 if (nvram_match("smbd_autoshare", "3")) // Hidden
1739 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1740 dp->d_name, MOUNT_ROOT, dp->d_name);
1741 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1742 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1744 cnt++;
1748 if (dir) closedir(dir);
1750 if (cnt == 0) {
1751 /* by default share MOUNT_ROOT as read-only */
1752 fprintf(fp, "\n[share]\n"
1753 " path = %s\n"
1754 " writable = no\n",
1755 MOUNT_ROOT);
1758 fclose(fp);
1760 mkdir_if_none("/var/run/samba");
1761 mkdir_if_none("/etc/samba");
1763 /* write smbpasswd */
1764 #ifdef TCONFIG_SAMBA3
1765 eval("smbpasswd", "nobody", "\"\"");
1766 #else
1767 eval("smbpasswd", "-a", "nobody", "\"\"");
1768 #endif
1769 if (mode == 2) {
1770 char *smbd_user;
1771 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1772 smbd_user = "nas";
1773 #ifdef TCONFIG_SAMBA3
1774 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1775 #else
1776 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1777 #endif
1780 kill_samba(SIGHUP);
1781 int ret1 = 0, ret2 = 0;
1782 /* start samba if it's not already running */
1783 if (pidof("nmbd") <= 0)
1784 ret1 = xstart("nmbd", "-D");
1785 if (pidof("smbd") <= 0)
1786 ret2 = xstart("smbd", "-D");
1788 if (ret1 || ret2) kill_samba(SIGTERM);
1791 static void stop_samba(void)
1793 if (getpid() != 1) {
1794 stop_service("smbd");
1795 return;
1798 kill_samba(SIGTERM);
1799 /* clean up */
1800 unlink("/var/log/smb");
1801 unlink("/var/log/nmb");
1802 eval("rm", "-rf", "/var/run/samba");
1804 #endif // TCONFIG_SAMBASRV
1806 #ifdef TCONFIG_MEDIA_SERVER
1807 #define MEDIA_SERVER_APP "minidlna"
1809 static void start_media_server(void)
1811 FILE *f;
1812 int port, pid, https;
1813 char *dbdir;
1814 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1815 static int once = 1;
1817 if (getpid() != 1) {
1818 start_service("media");
1819 return;
1822 if (nvram_get_int("ms_sas") == 0)
1823 once = 0;
1825 if (nvram_get_int("ms_enable") != 0) {
1826 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
1827 // no forced rescan
1828 argv[3] = NULL;
1830 nvram_unset("ms_rescan");
1832 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
1833 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
1835 else {
1836 if ((f = fopen(argv[2], "w")) != NULL) {
1837 port = nvram_get_int("ms_port");
1838 https = nvram_get_int("https_enable");
1839 dbdir = nvram_safe_get("ms_dbdir");
1840 if (!(*dbdir)) dbdir = NULL;
1841 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
1843 fprintf(f,
1844 "network_interface=%s\n"
1845 "port=%d\n"
1846 "friendly_name=%s\n"
1847 "db_dir=%s/.db\n"
1848 "enable_tivo=%s\n"
1849 "strict_dlna=%s\n"
1850 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1851 "inotify=yes\n"
1852 "notify_interval=600\n"
1853 "album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg\n"
1854 "\n",
1855 nvram_safe_get("lan_ifname"),
1856 (port < 0) || (port >= 0xffff) ? 0 : port,
1857 nvram_get("router_name") ? : "Tomato",
1858 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
1859 nvram_get_int("ms_tivo") ? "yes" : "no",
1860 nvram_get_int("ms_stdlna") ? "yes" : "no",
1861 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
1864 // media directories
1865 char *buf, *p, *q;
1866 char *path, *restrict;
1868 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
1869 /* path<restrict[A|V|P|] */
1871 p = buf;
1872 while ((q = strsep(&p, ">")) != NULL) {
1873 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
1874 continue;
1875 fprintf(f, "media_dir=%s%s%s\n",
1876 restrict ? : "", (restrict && *restrict) ? "," : "", path);
1878 free(buf);
1881 fclose(f);
1885 /* start media server if it's not already running */
1886 if (pidof(MEDIA_SERVER_APP) <= 0) {
1887 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
1888 /* If we started the media server successfully, wait 1 sec
1889 * to let it die if it can't open the database file.
1890 * If it's still alive after that, assume it's running and
1891 * disable forced once-after-reboot rescan.
1893 sleep(1);
1894 if (pidof(MEDIA_SERVER_APP) > 0)
1895 once = 0;
1901 static void stop_media_server(void)
1903 if (getpid() != 1) {
1904 stop_service("media");
1905 return;
1908 killall_tk(MEDIA_SERVER_APP);
1910 #endif // TCONFIG_MEDIA_SERVER
1912 #ifdef TCONFIG_USB
1913 static void start_nas_services(void)
1915 if (getpid() != 1) {
1916 start_service("usbapps");
1917 return;
1920 #ifdef TCONFIG_SAMBASRV
1921 start_samba();
1922 #endif
1923 #ifdef TCONFIG_FTP
1924 start_ftpd();
1925 #endif
1926 #ifdef TCONFIG_MEDIA_SERVER
1927 start_media_server();
1928 #endif
1929 #ifdef TCONFIG_UPS
1930 start_ups();
1931 #endif
1935 static void stop_nas_services(void)
1937 if (getpid() != 1) {
1938 stop_service("usbapps");
1939 return;
1942 #ifdef TCONFIG_MEDIA_SERVER
1943 stop_media_server();
1944 #endif
1945 #ifdef TCONFIG_FTP
1946 stop_ftpd();
1947 #endif
1948 #ifdef TCONFIG_SAMBASRV
1949 stop_samba();
1950 #endif
1951 #ifdef TCONFIG_UPS
1952 stop_ups();
1953 #endif
1957 void restart_nas_services(int stop, int start)
1959 int fd = file_lock("usb");
1960 /* restart all NAS applications */
1961 if (stop)
1962 stop_nas_services();
1963 if (start)
1964 start_nas_services();
1965 file_unlock(fd);
1967 #endif // TCONFIG_USB
1969 // -----------------------------------------------------------------------------
1971 /* -1 = Don't check for this program, it is not expected to be running.
1972 * Other = This program has been started and should be kept running. If no
1973 * process with the name is running, call func to restart it.
1974 * Note: At startup, dnsmasq forks a short-lived child which forks a
1975 * long-lived (grand)child. The parents terminate.
1976 * Many daemons use this technique.
1978 static void _check(pid_t pid, const char *name, void (*func)(void))
1980 if (pid == -1) return;
1982 if (pidof(name) > 0) return;
1984 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
1985 func();
1987 // Force recheck in 500 msec
1988 setitimer(ITIMER_REAL, &pop_tv, NULL);
1991 void check_services(void)
1993 TRACE_PT("keep alive\n");
1995 // Periodically reap any zombies
1996 setitimer(ITIMER_REAL, &zombie_tv, NULL);
1998 #ifdef LINUX26
1999 _check(pid_hotplug2, "hotplug2", start_hotplug2);
2000 #endif
2001 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
2002 _check(pid_crond, "crond", start_cron);
2003 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
2004 #ifdef TCONFIG_IPV6
2005 _check(pid_radvd, "radvd", start_radvd);
2006 #endif
2008 //#ifdef TCONFIG_NOCAT
2009 // if (nvram_get_int("NC_enable"))
2010 // _check(&pid_splashd, "splashd", start_splashd);
2011 //#endif
2015 // -----------------------------------------------------------------------------
2017 void start_services(void)
2019 static int once = 1;
2021 if (once) {
2022 once = 0;
2024 if (nvram_get_int("telnetd_eas")) start_telnetd();
2025 if (nvram_get_int("sshd_eas")) start_sshd();
2028 // start_syslog();
2029 start_nas();
2030 start_zebra();
2031 #ifdef TCONFIG_SDHC
2032 start_mmc();
2033 #endif
2034 start_dnsmasq();
2035 start_cifs();
2036 start_httpd();
2037 start_cron();
2038 // start_upnp();
2039 start_rstats(0);
2040 start_cstats(0);
2041 start_sched();
2042 #ifdef TCONFIG_IPV6
2043 /* note: starting radvd here might be too early in case of
2044 * DHCPv6 or 6to4 because we won't have received a prefix and
2045 * so it will disable advertisements. To restart them, we have
2046 * to send radvd a SIGHUP, or restart it.
2048 start_radvd();
2049 #endif
2050 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2052 #ifdef TCONFIG_SNMP
2053 start_snmp();
2054 #endif
2056 #ifdef TCONFIG_BT
2057 start_bittorrent();
2058 #endif
2060 #ifdef TCONFIG_NFS
2061 start_nfs();
2062 #endif
2065 void stop_services(void)
2067 clear_resolv();
2069 #ifdef TCONFIG_BT
2070 stop_bittorrent();
2071 #endif
2073 #ifdef TCONFIG_SNMP
2074 stop_snmp();
2075 #endif
2077 #ifdef TCONFIG_NFS
2078 stop_nfs();
2079 #endif
2080 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2081 #ifdef TCONFIG_IPV6
2082 stop_radvd();
2083 #endif
2084 stop_sched();
2085 stop_rstats();
2086 stop_cstats();
2087 // stop_upnp();
2088 stop_cron();
2089 stop_httpd();
2090 #ifdef TCONFIG_SDHC
2091 stop_mmc();
2092 #endif
2093 stop_cifs();
2094 stop_dnsmasq();
2095 stop_zebra();
2096 stop_nas();
2097 // stop_syslog();
2100 // -----------------------------------------------------------------------------
2102 /* nvram "action_service" is: "service-action[-modifier]"
2103 * action is something like "stop" or "start" or "restart"
2104 * optional modifier is "c" for the "service" command-line command
2106 void exec_service(void)
2108 const int A_START = 1;
2109 const int A_STOP = 2;
2110 const int A_RESTART = 1|2;
2111 char buffer[128];
2112 char *service;
2113 char *act;
2114 char *next;
2115 char *modifier;
2116 int action, user;
2117 int i;
2119 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
2120 next = buffer;
2122 TOP:
2123 act = strsep(&next, ",");
2124 service = strsep(&act, "-");
2125 if (act == NULL) {
2126 next = NULL;
2127 goto CLEAR;
2129 modifier = act;
2130 strsep(&modifier, "-");
2132 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
2134 if (strcmp(act, "start") == 0) action = A_START;
2135 else if (strcmp(act, "stop") == 0) action = A_STOP;
2136 else if (strcmp(act, "restart") == 0) action = A_RESTART;
2137 else action = 0;
2138 user = (modifier != NULL && *modifier == 'c');
2140 if (strcmp(service, "dhcpc") == 0) {
2141 if (action & A_STOP) stop_dhcpc();
2142 if (action & A_START) start_dhcpc();
2143 goto CLEAR;
2146 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
2147 if (action & A_STOP) stop_dnsmasq();
2148 if (action & A_START) {
2149 dns_to_resolv();
2150 start_dnsmasq();
2152 goto CLEAR;
2155 if (strcmp(service, "firewall") == 0) {
2156 if (action & A_STOP) {
2157 stop_firewall();
2158 stop_igmp_proxy();
2160 if (action & A_START) {
2161 start_firewall();
2162 start_igmp_proxy();
2164 goto CLEAR;
2167 if (strcmp(service, "restrict") == 0) {
2168 if (action & A_STOP) {
2169 stop_firewall();
2171 if (action & A_START) {
2172 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2174 start_firewall();
2176 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2177 if (i == 1) {
2178 if (nvram_get_int("rrules_radio") < 0) {
2179 eval("radio", "on");
2183 goto CLEAR;
2186 if (strcmp(service, "arpbind") == 0) {
2187 if (action & A_STOP) stop_arpbind();
2188 if (action & A_START) start_arpbind();
2189 goto CLEAR;
2192 if (strcmp(service, "qos") == 0) {
2193 if (action & A_STOP) {
2194 stop_qos();
2196 stop_firewall(); start_firewall(); // always restarted
2197 if (action & A_START) {
2198 start_qos();
2199 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2201 goto CLEAR;
2204 if (strcmp(service, "qoslimit") == 0) {
2205 if (action & A_STOP) {
2206 new_qoslimit_stop();
2208 stop_firewall(); start_firewall(); // always restarted
2209 if (action & A_START) {
2210 new_qoslimit_start();
2212 goto CLEAR;
2215 if (strcmp(service, "upnp") == 0) {
2216 if (action & A_STOP) {
2217 stop_upnp();
2219 stop_firewall(); start_firewall(); // always restarted
2220 if (action & A_START) {
2221 start_upnp();
2223 goto CLEAR;
2226 if (strcmp(service, "telnetd") == 0) {
2227 if (action & A_STOP) stop_telnetd();
2228 if (action & A_START) start_telnetd();
2229 goto CLEAR;
2232 if (strcmp(service, "sshd") == 0) {
2233 if (action & A_STOP) stop_sshd();
2234 if (action & A_START) start_sshd();
2235 goto CLEAR;
2238 if (strcmp(service, "httpd") == 0) {
2239 if (action & A_STOP) stop_httpd();
2240 if (action & A_START) start_httpd();
2241 goto CLEAR;
2244 #ifdef TCONFIG_IPV6
2245 if (strcmp(service, "ipv6") == 0) {
2246 if (action & A_STOP) {
2247 stop_radvd();
2248 stop_ipv6();
2250 if (action & A_START) {
2251 start_ipv6();
2252 start_radvd();
2254 goto CLEAR;
2257 if (strcmp(service, "radvd") == 0) {
2258 if (action & A_STOP) {
2259 stop_radvd();
2261 if (action & A_START) {
2262 start_radvd();
2264 goto CLEAR;
2267 if (strncmp(service, "dhcp6", 5) == 0) {
2268 if (action & A_STOP) {
2269 stop_dhcp6c();
2271 if (action & A_START) {
2272 start_dhcp6c();
2274 goto CLEAR;
2276 #endif
2278 if (strcmp(service, "admin") == 0) {
2279 if (action & A_STOP) {
2280 stop_sshd();
2281 stop_telnetd();
2282 stop_httpd();
2284 stop_firewall(); start_firewall(); // always restarted
2285 if (action & A_START) {
2286 start_httpd();
2287 create_passwd();
2288 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2289 if (nvram_match("sshd_eas", "1")) start_sshd();
2291 goto CLEAR;
2294 if (strcmp(service, "ddns") == 0) {
2295 if (action & A_STOP) stop_ddns();
2296 if (action & A_START) start_ddns();
2297 goto CLEAR;
2300 if (strcmp(service, "ntpc") == 0) {
2301 if (action & A_STOP) stop_ntpc();
2302 if (action & A_START) start_ntpc();
2303 goto CLEAR;
2306 if (strcmp(service, "logging") == 0) {
2307 if (action & A_STOP) {
2308 stop_syslog();
2310 if (action & A_START) {
2311 start_syslog();
2313 if (!user) {
2314 // always restarted except from "service" command
2315 stop_cron(); start_cron();
2316 stop_firewall(); start_firewall();
2318 goto CLEAR;
2321 if (strcmp(service, "crond") == 0) {
2322 if (action & A_STOP) {
2323 stop_cron();
2325 if (action & A_START) {
2326 start_cron();
2328 goto CLEAR;
2331 #ifdef LINUX26
2332 if (strncmp(service, "hotplug", 7) == 0) {
2333 if (action & A_STOP) {
2334 stop_hotplug2();
2336 if (action & A_START) {
2337 start_hotplug2(1);
2339 goto CLEAR;
2341 #endif
2343 if (strcmp(service, "upgrade") == 0) {
2344 if (action & A_START) {
2345 #if TOMATO_SL
2346 stop_usbevent();
2347 stop_smbd();
2348 #endif
2349 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2350 stop_jffs2();
2351 // stop_cifs();
2352 stop_zebra();
2353 stop_cron();
2354 stop_ntpc();
2355 stop_upnp();
2356 // stop_dhcpc();
2357 killall("rstats", SIGTERM);
2358 killall("cstats", SIGTERM);
2359 killall("buttons", SIGTERM);
2360 stop_syslog();
2361 remove_storage_main(1); // !!TB - USB Support
2362 stop_usb(); // !!TB - USB Support
2364 goto CLEAR;
2367 #ifdef TCONFIG_CIFS
2368 if (strcmp(service, "cifs") == 0) {
2369 if (action & A_STOP) stop_cifs();
2370 if (action & A_START) start_cifs();
2371 goto CLEAR;
2373 #endif
2375 #ifdef TCONFIG_JFFS2
2376 if (strncmp(service, "jffs", 4) == 0) {
2377 if (action & A_STOP) stop_jffs2();
2378 if (action & A_START) start_jffs2();
2379 goto CLEAR;
2381 #endif
2383 if (strcmp(service, "zebra") == 0) {
2384 if (action & A_STOP) stop_zebra();
2385 if (action & A_START) start_zebra();
2386 goto CLEAR;
2389 #ifdef TCONFIG_SDHC
2390 if (strcmp(service, "mmc") == 0) {
2391 if (action & A_STOP) stop_mmc();
2392 if (action & A_START) start_mmc();
2393 goto CLEAR;
2395 #endif
2397 if (strcmp(service, "routing") == 0) {
2398 if (action & A_STOP) {
2399 stop_zebra();
2400 do_static_routes(0); // remove old '_saved'
2401 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2402 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2403 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2404 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2405 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2406 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2407 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2409 stop_firewall();
2410 start_firewall();
2411 if (action & A_START) {
2412 do_static_routes(1); // add new
2413 start_zebra();
2414 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2415 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2416 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2417 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2418 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2419 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2420 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2422 goto CLEAR;
2425 if (strcmp(service, "ctnf") == 0) {
2426 if (action & A_START) {
2427 setup_conntrack();
2428 stop_firewall();
2429 start_firewall();
2431 goto CLEAR;
2434 if (strcmp(service, "wan") == 0) {
2435 if (action & A_STOP) {
2436 stop_wan();
2439 if (action & A_START) {
2440 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2441 start_wan(BOOT);
2442 sleep(2);
2443 force_to_dial();
2445 goto CLEAR;
2448 if (strcmp(service, "net") == 0) {
2449 if (action & A_STOP) {
2450 #ifdef TCONFIG_USB
2451 stop_nas_services();
2452 #endif
2453 #ifdef TCONFIG_IPV6
2454 stop_radvd();
2455 #endif
2456 stop_httpd();
2457 stop_dnsmasq();
2458 stop_nas();
2459 stop_wan();
2460 stop_arpbind();
2461 stop_lan();
2462 stop_vlan();
2464 if (action & A_START) {
2465 start_vlan();
2466 start_lan();
2467 start_arpbind();
2468 start_wan(BOOT);
2469 start_nas();
2470 start_dnsmasq();
2471 start_httpd();
2472 #ifdef TCONFIG_IPV6
2473 start_radvd();
2474 #endif
2475 start_wl();
2476 #ifdef TCONFIG_USB
2477 start_nas_services();
2478 #endif
2480 goto CLEAR;
2483 if (strcmp(service, "nas") == 0) {
2484 if (action & A_STOP) {
2485 stop_nas();
2487 if (action & A_START) {
2488 start_nas();
2489 start_wl();
2491 goto CLEAR;
2494 if (strcmp(service, "rstats") == 0) {
2495 if (action & A_STOP) stop_rstats();
2496 if (action & A_START) start_rstats(0);
2497 goto CLEAR;
2500 if (strcmp(service, "rstatsnew") == 0) {
2501 if (action & A_STOP) stop_rstats();
2502 if (action & A_START) start_rstats(1);
2503 goto CLEAR;
2506 if (strcmp(service, "cstats") == 0) {
2507 if (action & A_STOP) stop_cstats();
2508 if (action & A_START) start_cstats(0);
2509 goto CLEAR;
2512 if (strcmp(service, "cstatsnew") == 0) {
2513 if (action & A_STOP) stop_cstats();
2514 if (action & A_START) start_cstats(1);
2515 goto CLEAR;
2518 if (strcmp(service, "sched") == 0) {
2519 if (action & A_STOP) stop_sched();
2520 if (action & A_START) start_sched();
2521 goto CLEAR;
2524 #ifdef TCONFIG_BT
2525 if (strcmp(service, "bittorrent") == 0) {
2526 if (action & A_STOP) {
2527 stop_bittorrent();
2529 stop_firewall(); start_firewall(); // always restarted
2530 if (action & A_START) {
2531 start_bittorrent();
2533 goto CLEAR;
2535 #endif
2537 #ifdef TCONFIG_NFS
2538 if (strcmp(service, "nfs") == 0) {
2539 if (action & A_STOP) stop_nfs();
2540 if (action & A_START) start_nfs();
2541 goto CLEAR;
2543 #endif
2545 #ifdef TCONFIG_SNMP
2546 if (strcmp(service, "snmp") == 0) {
2547 if (action & A_STOP) stop_snmp();
2548 if (action & A_START) start_snmp();
2549 goto CLEAR;
2551 #endif
2553 #ifdef TCONFIG_UPS
2554 if (strcmp(service, "ups") == 0) {
2555 if (action & A_STOP) stop_ups();
2556 if (action & A_START) start_ups();
2557 goto CLEAR;
2559 #endif
2561 #ifdef TCONFIG_USB
2562 // !!TB - USB Support
2563 if (strcmp(service, "usb") == 0) {
2564 if (action & A_STOP) stop_usb();
2565 if (action & A_START) {
2566 start_usb();
2567 // restart Samba and ftp since they may be killed by stop_usb()
2568 restart_nas_services(0, 1);
2569 // remount all partitions by simulating hotplug event
2570 add_remove_usbhost("-1", 1);
2572 goto CLEAR;
2575 if (strcmp(service, "usbapps") == 0) {
2576 if (action & A_STOP) stop_nas_services();
2577 if (action & A_START) start_nas_services();
2578 goto CLEAR;
2580 #endif
2582 #ifdef TCONFIG_FTP
2583 // !!TB - FTP Server
2584 if (strcmp(service, "ftpd") == 0) {
2585 if (action & A_STOP) stop_ftpd();
2586 setup_conntrack();
2587 stop_firewall();
2588 start_firewall();
2589 if (action & A_START) start_ftpd();
2590 goto CLEAR;
2592 #endif
2594 #ifdef TCONFIG_MEDIA_SERVER
2595 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2596 if (action & A_STOP) stop_media_server();
2597 if (action & A_START) start_media_server();
2598 goto CLEAR;
2600 #endif
2602 #ifdef TCONFIG_SAMBASRV
2603 // !!TB - Samba
2604 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2605 if (action & A_STOP) stop_samba();
2606 if (action & A_START) {
2607 create_passwd();
2608 stop_dnsmasq();
2609 start_dnsmasq();
2610 start_samba();
2612 goto CLEAR;
2614 #endif
2616 #ifdef TCONFIG_OPENVPN
2617 if (strncmp(service, "vpnclient", 9) == 0) {
2618 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2619 if (action & A_START) start_vpnclient(atoi(&service[9]));
2620 goto CLEAR;
2623 if (strncmp(service, "vpnserver", 9) == 0) {
2624 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2625 if (action & A_START) start_vpnserver(atoi(&service[9]));
2626 goto CLEAR;
2628 #endif
2630 #ifdef TCONFIG_NOCAT
2631 if (strcmp(service, "splashd") == 0) {
2632 if (action & A_STOP) stop_splashd();
2633 if (action & A_START) start_splashd();
2634 goto CLEAR;
2636 #endif
2638 CLEAR:
2639 if (next) goto TOP;
2641 // some functions check action_service and must be cleared at end -- zzz
2642 nvram_set("action_service", "");
2644 // Force recheck in 500 msec
2645 setitimer(ITIMER_REAL, &pop_tv, NULL);
2648 static void do_service(const char *name, const char *action, int user)
2650 int n;
2651 char s[64];
2653 n = 150;
2654 while (!nvram_match("action_service", "")) {
2655 if (user) {
2656 putchar('*');
2657 fflush(stdout);
2659 else if (--n < 0) break;
2660 usleep(100 * 1000);
2663 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2664 nvram_set("action_service", s);
2666 if (nvram_match("debug_rc_svc", "1")) {
2667 nvram_unset("debug_rc_svc");
2668 exec_service();
2669 } else {
2670 kill(1, SIGUSR1);
2673 n = 150;
2674 while (nvram_match("action_service", s)) {
2675 if (user) {
2676 putchar('.');
2677 fflush(stdout);
2679 else if (--n < 0) {
2680 break;
2682 usleep(100 * 1000);
2686 int service_main(int argc, char *argv[])
2688 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2689 do_service(argv[1], argv[2], 1);
2690 printf("\nDone.\n");
2691 return 0;
2694 void start_service(const char *name)
2696 do_service(name, "start", 0);
2699 void stop_service(const char *name)
2701 do_service(name, "stop", 0);
2705 void restart_service(const char *name)
2707 do_service(name, "restart", 0);