- Allowed the IPv6 Forwarding page to allow more fancy subnets & rules.
[tomato.git] / release / src / router / rc / services.c
blobdf4f3d6678de441168ea7a4f429223e21b22545d
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 #ifdef TCONFIG_IPV6
90 char *prefix, *ipv6, *mtu;
91 int do_6to4, do_6rd;
92 int service;
93 #endif
95 TRACE_PT("begin\n");
97 if (getpid() != 1) {
98 start_service("dnsmasq");
99 return;
102 stop_dnsmasq();
104 if (foreach_wif(1, NULL, is_wet)) return;
106 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
108 router_ip = nvram_safe_get("lan_ipaddr");
110 fprintf(f,
111 "pid-file=/var/run/dnsmasq.pid\n");
112 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
113 if (*nv) fprintf(f, "domain=%s\n", nv);
116 // dns
117 const dns_list_t *dns = get_dns(); // this always points to a static buffer
119 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
120 else n = 4096;
121 fprintf(f,
122 "resolv-file=%s\n" // the real stuff is here
123 "addn-hosts=%s\n" // directory with additional hosts files
124 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
125 "expand-hosts\n" // expand hostnames in hosts file
126 "min-port=%u\n", // min port used for random src port
127 dmresolv, dmhosts, dmdhcp, n);
128 do_dns = nvram_match("dhcpd_dmdns", "1");
130 // DNS rebinding protection, will discard upstream RFC1918 responses
131 if (nvram_get_int("dns_norebind")) {
132 fprintf(f,
133 "stop-dns-rebind\n"
134 "rebind-localhost-ok\n");
135 // allow RFC1918 responses for server domain
136 switch (get_wan_proto()) {
137 case WP_PPTP:
138 nv = nvram_get("pptp_server_ip");
139 break;
140 case WP_L2TP:
141 nv = nvram_get("l2tp_server_ip");
142 break;
143 default:
144 nv = NULL;
145 break;
147 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
150 for (n = 0 ; n < dns->count; ++n) {
151 if (dns->dns[n].port != 53) {
152 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
156 if (nvram_get_int("dhcpd_static_only")) {
157 fprintf(f, "dhcp-ignore=tag:!known\n");
160 if ((n = nvram_get_int("dnsmasq_q"))) { //process quiet flags
161 if (n & 1) fprintf(f, "quiet-dhcp\n");
162 if (n & 2) fprintf(f, "quiet-dhcp6\n");
163 if (n & 4) fprintf(f, "quiet-ra\n");
166 // dhcp
167 do_dhcpd_hosts=0;
168 char lanN_proto[] = "lanXX_proto";
169 char lanN_ifname[] = "lanXX_ifname";
170 char lanN_ipaddr[] = "lanXX_ipaddr";
171 char lanN_netmask[] = "lanXX_netmask";
172 char dhcpdN_startip[] = "dhcpdXX_startip";
173 char dhcpdN_endip[] = "dhcpdXX_endip";
174 char dhcpN_start[] = "dhcpXX_start";
175 char dhcpN_num[] = "dhcpXX_num";
176 char dhcpN_lease[] = "dhcpXX_lease";
177 char br;
178 for(br=0 ; br<=3 ; br++) {
179 char bridge[2] = "0";
180 if (br!=0)
181 bridge[0]+=br;
182 else
183 strcpy(bridge, "");
185 sprintf(lanN_proto, "lan%s_proto", bridge);
186 sprintf(lanN_ifname, "lan%s_ifname", bridge);
187 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
188 do_dhcpd = nvram_match(lanN_proto, "dhcp");
189 if (do_dhcpd) {
190 do_dhcpd_hosts++;
192 router_ip = nvram_safe_get(lanN_ipaddr);
193 strlcpy(lan, router_ip, sizeof(lan));
194 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
196 fprintf(f,
197 "interface=%s\n",
198 nvram_safe_get(lanN_ifname));
200 sprintf(dhcpN_lease, "dhcp%s_lease", bridge);
201 dhcp_lease = nvram_get_int(dhcpN_lease);
203 if (dhcp_lease <= 0) dhcp_lease = 1440;
205 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
206 if (n < 0) strcpy(sdhcp_lease, "infinite");
207 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
209 if (!do_dns) {
210 // if not using dnsmasq for dns
212 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
213 // no DNS might be temporary. use a low lease time to force clients to update.
214 dhcp_lease = 2;
215 strcpy(sdhcp_lease, "2m");
216 do_dns = 1;
218 else {
219 // pass the dns directly
220 buf[0] = 0;
221 for (n = 0 ; n < dns->count; ++n) {
222 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
223 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
226 fprintf(f, "dhcp-option=tag:%s,6%s\n", nvram_safe_get(lanN_ifname), buf);
230 sprintf(dhcpdN_startip, "dhcpd%s_startip", bridge);
231 sprintf(dhcpdN_endip, "dhcpd%s_endip", bridge);
232 sprintf(lanN_netmask, "lan%s_netmask", bridge);
234 if ((p = nvram_get(dhcpdN_startip)) && (*p) && (e = nvram_get(dhcpdN_endip)) && (*e)) {
235 fprintf(f, "dhcp-range=tag:%s,%s,%s,%s,%dm\n", nvram_safe_get(lanN_ifname), p, e, nvram_safe_get(lanN_netmask), dhcp_lease);
237 else {
238 // for compatibility
239 sprintf(dhcpN_start, "dhcp%s_start", bridge);
240 sprintf(dhcpN_num, "dhcp%s_num", bridge);
241 sprintf(lanN_netmask, "lan%s_netmask", bridge);
242 dhcp_start = nvram_get_int(dhcpN_start);
243 dhcp_count = nvram_get_int(dhcpN_num);
244 fprintf(f, "dhcp-range=tag:%s,%s%d,%s%d,%s,%dm\n",
245 nvram_safe_get(lanN_ifname), lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get(lanN_netmask), dhcp_lease);
248 nv = nvram_safe_get(lanN_ipaddr);
249 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
250 p = nvram_safe_get("lan_gateway");
251 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
253 #ifdef TCONFIG_VLAN
254 fprintf(f,
255 "dhcp-option=tag:%s,3,%s\n", // gateway
256 nvram_safe_get(lanN_ifname), nv);
257 #endif
258 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
259 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nv);
261 #ifdef TCONFIG_SAMBASRV
262 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
263 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
264 // Samba will serve as a WINS server
265 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nvram_safe_get(lanN_ipaddr));
268 #endif
269 } else {
270 if (strcmp(nvram_safe_get(lanN_ifname),"")!=0) {
271 fprintf(f, "interface=%s\n", nvram_safe_get(lanN_ifname));
272 // if no dhcp range is set then no dhcp service will be offered so following
273 // line is superflous.
274 // fprintf(f, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname));
278 // write static lease entries & create hosts file
280 mkdir_if_none(dmhosts);
281 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
282 if ((hf = fopen(buf, "w")) != NULL) {
283 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
284 fprintf(hf, "%s %s\n", router_ip, nv);
285 #ifdef TCONFIG_SAMBASRV
286 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
287 fprintf(hf, "%s %s\n", router_ip, nv);
288 #endif
289 p = (char *)get_wanip();
290 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
291 p = "127.0.0.1";
292 fprintf(hf, "%s wan-ip\n", p);
293 if (nv && (*nv))
294 fprintf(hf, "%s %s-wan\n", p, nv);
298 mkdir_if_none(dmdhcp);
299 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
300 df = fopen(buf, "w");
302 // PREVIOUS/OLD FORMAT:
303 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 73 w/ delim
304 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
305 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 103 w/ delim
307 // NEW FORMAT (+static ARP binding flag after hostname):
308 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 75 w/ delim
309 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
310 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 105 w/ delim
312 p = nvram_safe_get("dhcpd_static");
313 while ((e = strchr(p, '>')) != NULL) {
314 n = (e - p);
315 if (n > 104) {
316 p = e + 1;
317 continue;
320 strncpy(buf, p, n);
321 buf[n] = 0;
322 p = e + 1;
324 if ((e = strchr(buf, '<')) == NULL) continue;
325 *e = 0;
326 mac = buf;
328 ip = e + 1;
329 if ((e = strchr(ip, '<')) == NULL) continue;
330 *e = 0;
331 if (strchr(ip, '.') == NULL) {
332 ipn = atoi(ip);
333 if ((ipn <= 0) || (ipn > 255)) continue;
334 sprintf(ipbuf, "%s%d", lan, ipn);
335 ip = ipbuf;
337 else {
338 if (inet_addr(ip) == INADDR_NONE) continue;
341 name = e + 1;
343 if ((e = strchr(name, '<')) != NULL) {
344 *e = 0;
347 if ((hf) && (*name != 0)) {
348 fprintf(hf, "%s %s\n", ip, name);
351 if ((do_dhcpd_hosts > 0) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
352 char static_dhcp_lease[32];
353 strcpy(static_dhcp_lease, "");
354 if (nvram_get_int("dhcpd_slt") != 0)
355 sprintf(static_dhcp_lease, ",%s", sdhcp_lease);
356 if (df)
357 fprintf(df, "%s,%s%s\n", mac, ip, static_dhcp_lease);
358 else
359 fprintf(f, "dhcp-host=%s,%s%s\n", mac, ip, static_dhcp_lease);
363 if (df) fclose(df);
364 if (hf) fclose(hf);
366 n = nvram_get_int("dhcpd_lmax");
367 fprintf(f,
368 "dhcp-lease-max=%d\n",
369 (n > 0) ? n : 255);
370 if (nvram_get_int("dhcpd_auth") >= 0) {
371 fprintf(f, "dhcp-authoritative\n");
376 #ifdef TCONFIG_OPENVPN
377 write_vpn_dnsmasq_config(f);
378 #endif
380 #ifdef TCONFIG_PPTPD
381 write_pptpd_dnsmasq_config(f);
382 #endif
384 #ifdef TCONFIG_IPV6
385 if (ipv6_enabled()) {
387 service = get_ipv6_service();
388 do_6to4 = (service == IPV6_ANYCAST_6TO4);
389 do_6rd = (service == IPV6_6RD || service == IPV6_6RD_DHCP);
390 mtu = NULL;
391 switch (service) {
392 case IPV6_NATIVE_DHCP:
393 case IPV6_ANYCAST_6TO4:
394 case IPV6_6IN4:
395 case IPV6_6RD:
396 case IPV6_6RD_DHCP:
397 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
398 // fall through
399 default:
400 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
401 break;
403 if (!(*prefix)) prefix = "::";
404 ipv6 = (char *)ipv6_router_address(NULL);
405 fprintf(f, "enable-ra\ndhcp-range=tag:br0,%s, slaac, ra-names, 64\n", prefix);
407 // enable-ra should be enabled in both cases
408 if (nvram_get_int("ipv6_radvd") || nvram_get_int("ipv6_dhcpd"))
409 fprintf(f,"enable-ra\n");
411 // Only SLAAC and NO DHCPv6
412 if (nvram_get_int("ipv6_radvd") && !nvram_get_int("ipv6_dhcpd"))
413 fprintf(f,"dhcp-range=::, constructor:br*, ra-names, ra-stateless, 64, 12h\n");
415 // Only DHCPv6 and NO SLAAC
416 if (nvram_get_int("ipv6_dhcpd") && !nvram_get_int("ipv6_radvd"))
417 fprintf(f,"dhcp-range=::1, ::FFFF:FFFF, constructor:br*, 64, 12h\n");
419 // SLAAC and DHCPv6 (2 IPv6 IPs)
420 if (nvram_get_int("ipv6_radvd") && nvram_get_int("ipv6_dhcpd"))
421 fprintf(f,"dhcp-range=::1, ::FFFF:FFFF, constructor:br*, ra-names, 64, 12h\n");
423 #endif
425 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
427 fappend(f, "/etc/dnsmasq.custom");
431 fclose(f);
433 if (do_dns) {
434 unlink("/etc/resolv.conf");
435 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
438 TRACE_PT("run dnsmasq\n");
440 // Default to some values we like, but allow the user to override them.
441 eval("dnsmasq", "-c", "1500", "--log-async");
443 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
444 pid_dnsmasq = -2;
447 TRACE_PT("end\n");
450 void stop_dnsmasq(void)
452 TRACE_PT("begin\n");
454 if (getpid() != 1) {
455 stop_service("dnsmasq");
456 return;
459 pid_dnsmasq = -1;
461 unlink("/etc/resolv.conf");
462 symlink(dmresolv, "/etc/resolv.conf");
464 killall_tk("dnsmasq");
466 TRACE_PT("end\n");
469 void clear_resolv(void)
471 f_write(dmresolv, NULL, 0, 0, 0); // blank
474 #ifdef TCONFIG_IPV6
475 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
477 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
478 struct in6_addr addr;
479 int cnt = 0;
481 foreach(p, dns, next) {
482 // verify that this is a valid IPv6 address
483 if (inet_pton(AF_INET6, p, &addr) == 1) {
484 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
485 ++cnt;
489 return cnt;
491 #endif
493 void dns_to_resolv(void)
495 FILE *f;
496 const dns_list_t *dns;
497 int i;
498 mode_t m;
500 m = umask(022); // 077 from pppoecd
501 if ((f = fopen(dmresolv, "w")) != NULL) {
502 // Check for VPN DNS entries
503 if (!write_pptpvpn_resolv(f) && !write_vpn_resolv(f)) {
504 #ifdef TCONFIG_IPV6
505 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
506 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
507 #endif
508 dns = get_dns(); // static buffer
509 if (dns->count == 0) {
510 // Put a pseudo DNS IP to trigger Connect On Demand
511 if (nvram_match("ppp_demand", "1")) {
512 switch (get_wan_proto()) {
513 case WP_PPPOE:
514 case WP_PPP3G:
515 case WP_PPTP:
516 case WP_L2TP:
517 fprintf(f, "nameserver 1.1.1.1\n");
518 break;
522 else {
523 for (i = 0; i < dns->count; i++) {
524 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
525 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
530 fclose(f);
532 umask(m);
535 // -----------------------------------------------------------------------------
537 void start_httpd(void)
539 if (getpid() != 1) {
540 start_service("httpd");
541 return;
544 stop_httpd();
545 chdir("/www");
546 eval("httpd");
547 chdir("/");
550 void stop_httpd(void)
552 if (getpid() != 1) {
553 stop_service("httpd");
554 return;
557 killall_tk("httpd");
560 // -----------------------------------------------------------------------------
561 #ifdef TCONFIG_IPV6
563 static void add_ip6_lanaddr(void)
565 char ip[INET6_ADDRSTRLEN + 4];
566 const char *p;
568 p = ipv6_router_address(NULL);
569 if (*p) {
570 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
571 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
575 void start_ipv6_tunnel(void)
577 char ip[INET6_ADDRSTRLEN + 4];
578 struct in_addr addr4;
579 struct in6_addr addr;
580 const char *wanip, *mtu, *tun_dev;
581 int service;
583 service = get_ipv6_service();
584 tun_dev = get_wan6face();
585 wanip = get_wanip();
586 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
587 modprobe("sit");
589 if (service == IPV6_ANYCAST_6TO4)
590 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
591 else
592 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
593 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
594 "remote", ip,
595 "local", (char *)wanip,
596 "ttl", nvram_safe_get("ipv6_tun_ttl"));
598 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
599 nvram_set("ipv6_ifname", (char *)tun_dev);
601 if (service == IPV6_ANYCAST_6TO4) {
602 add_ip6_lanaddr();
603 addr4.s_addr = 0;
604 memset(&addr, 0, sizeof(addr));
605 inet_aton(wanip, &addr4);
606 addr.s6_addr16[0] = htons(0x2002);
607 ipv6_mapaddr4(&addr, 16, &addr4, 0);
608 addr.s6_addr16[7] = htons(0x0001);
609 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
610 strncat(ip, "/16", sizeof(ip));
612 else {
613 snprintf(ip, sizeof(ip), "%s/%d",
614 nvram_safe_get("ipv6_tun_addr"),
615 nvram_get_int("ipv6_tun_addrlen") ? : 64);
617 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
618 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
620 // (re)start radvd - now dnsmasq provided
621 if (service == IPV6_ANYCAST_6TO4)
622 start_dnsmasq();
625 void stop_ipv6_tunnel(void)
627 eval("ip", "tunnel", "del", (char *)get_wan6face());
628 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
629 // get rid of old IPv6 address from lan iface
630 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
632 modprobe_r("sit");
635 void start_6rd_tunnel(void)
637 const char *tun_dev, *wanip;
638 int service, mask_len, prefix_len, local_prefix_len;
639 char mtu[10], prefix[INET6_ADDRSTRLEN], relay[INET_ADDRSTRLEN];
640 struct in_addr netmask_addr, relay_addr, relay_prefix_addr, wanip_addr;
641 struct in6_addr prefix_addr, local_prefix_addr;
642 char local_prefix[INET6_ADDRSTRLEN];
643 char tmp_ipv6[INET6_ADDRSTRLEN + 4], tmp_ipv4[INET_ADDRSTRLEN + 4];
644 char tmp[256];
645 FILE *f;
647 service = get_ipv6_service();
648 wanip = get_wanip();
649 tun_dev = get_wan6face();
650 sprintf(mtu, "%d", (nvram_get_int("wan_mtu") > 0) ? (nvram_get_int("wan_mtu") - 20) : 1280);
652 // maybe we can merge the ipv6_6rd_* variables into a single ipv_6rd_string (ala wan_6rd)
653 // to save nvram space?
654 if (service == IPV6_6RD) {
655 _dprintf("starting 6rd tunnel using manual settings.\n");
656 mask_len = nvram_get_int("ipv6_6rd_ipv4masklen");
657 prefix_len = nvram_get_int("ipv6_6rd_prefix_length");
658 strcpy(prefix, nvram_safe_get("ipv6_6rd_prefix"));
659 strcpy(relay, nvram_safe_get("ipv6_6rd_borderrelay"));
661 else {
662 _dprintf("starting 6rd tunnel using automatic settings.\n");
663 char *wan_6rd = nvram_safe_get("wan_6rd");
664 if (sscanf(wan_6rd, "%d %d %s %s", &mask_len, &prefix_len, prefix, relay) < 4) {
665 _dprintf("wan_6rd string is missing or invalid (%s)\n", wan_6rd);
666 return;
670 // validate values that were passed
671 if (mask_len < 0 || mask_len > 32) {
672 _dprintf("invalid mask_len value (%d)\n", mask_len);
673 return;
675 if (prefix_len < 0 || prefix_len > 128) {
676 _dprintf("invalid prefix_len value (%d)\n", prefix_len);
677 return;
679 if ((32 - mask_len) + prefix_len > 128) {
680 _dprintf("invalid combination of mask_len and prefix_len!\n");
681 return;
684 sprintf(tmp, "ping -q -c 2 %s | grep packet", relay);
685 if ((f = popen(tmp, "r")) == NULL) {
686 _dprintf("error obtaining data\n");
687 return;
689 fgets(tmp, sizeof(tmp), f);
690 pclose(f);
691 if (strstr(tmp, " 0% packet loss") == NULL) {
692 _dprintf("failed to ping border relay\n");
693 return;
696 // get relay prefix from border relay address and mask
697 netmask_addr.s_addr = htonl(0xffffffff << (32 - mask_len));
698 inet_aton(relay, &relay_addr);
699 relay_prefix_addr.s_addr = relay_addr.s_addr & netmask_addr.s_addr;
701 // calculate the local prefix
702 inet_pton(AF_INET6, prefix, &prefix_addr);
703 inet_pton(AF_INET, wanip, &wanip_addr);
704 if (calc_6rd_local_prefix(&prefix_addr, prefix_len, mask_len,
705 &wanip_addr, &local_prefix_addr, &local_prefix_len) == 0) {
706 _dprintf("error calculating local prefix.");
707 return;
709 inet_ntop(AF_INET6, &local_prefix_addr, local_prefix, sizeof(local_prefix));
711 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1", local_prefix);
712 nvram_set("ipv6_rtr_addr", tmp_ipv6);
713 nvram_set("ipv6_prefix", local_prefix);
715 // load sit module needed for the 6rd tunnel
716 modprobe("sit");
718 // creating the 6rd tunnel
719 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit", "local", (char *)wanip, "ttl", nvram_safe_get("ipv6_tun_ttl"));
721 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s/%d", prefix, prefix_len);
722 snprintf(tmp_ipv4, sizeof(tmp_ipv4), "%s/%d", inet_ntoa(relay_prefix_addr), mask_len);
723 eval("ip", "tunnel" "6rd", "dev", (char *)tun_dev, "6rd-prefix", tmp_ipv6, "6rd-relay_prefix", tmp_ipv4);
725 // bringing up the link
726 eval("ip", "link", "set", "dev", (char *)tun_dev, "mtu", (char *)mtu, "up");
728 // setting the WAN address Note: IPv6 WAN CIDR should be: ((32 - ip6rd_ipv4masklen) + ip6rd_prefixlen)
729 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, local_prefix_len);
730 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", (char *)tun_dev);
732 // setting the LAN address Note: IPv6 LAN CIDR should be 64
733 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, nvram_get_int("ipv6_prefix_length") ? : 64);
734 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", nvram_safe_get("lan_ifname"));
736 // adding default route via the border relay
737 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "::%s", relay);
738 eval("ip", "-6", "route", "add", "default", "via", tmp_ipv6, "dev", (char *)tun_dev);
740 nvram_set("ipv6_ifname", (char *)tun_dev);
742 // (re)start radvd
743 start_radvd();
745 printf("6rd end\n");
748 void stop_6rd_tunnel(void)
750 eval("ip", "tunnel", "del", (char *)get_wan6face());
751 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
752 modprobe_r("sit");
755 static pid_t pid_radvd = -1;
757 void start_radvd(void)
759 FILE *f;
760 char *prefix, *ip, *mtu;
761 int do_dns, do_6to4, do_6rd;
762 char *argv[] = { "radvd", NULL, NULL, NULL };
763 int pid, argc, service, cnt;
765 if (getpid() != 1) {
766 start_service("radvd");
767 return;
770 stop_radvd();
772 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
773 service = get_ipv6_service();
774 do_6to4 = (service == IPV6_ANYCAST_6TO4);
775 do_6rd = (service == IPV6_6RD || service == IPV6_6RD_DHCP);
776 mtu = NULL;
778 switch (service) {
779 case IPV6_NATIVE_DHCP:
780 prefix = "::";
781 break;
782 case IPV6_ANYCAST_6TO4:
783 case IPV6_6IN4:
784 case IPV6_6RD:
785 case IPV6_6RD_DHCP:
786 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
787 // fall through
788 default:
789 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
790 break;
792 if (!(*prefix)) prefix = "::";
794 // Create radvd.conf
795 if ((f = fopen("/etc/radvd.conf", "w")) == NULL) return;
797 ip = (char *)ipv6_router_address(NULL);
798 do_dns = (*ip) && nvram_match("dhcpd_dmdns", "1");
800 fprintf(f,
801 "interface %s\n"
802 "{\n"
803 " IgnoreIfMissing on;\n"
804 " AdvSendAdvert on;\n"
805 " MaxRtrAdvInterval 60;\n"
806 " AdvHomeAgentFlag off;\n"
807 " AdvManagedFlag off;\n"
808 "%s%s%s"
809 " prefix %s/64 \n"
810 " {\n"
811 " AdvOnLink on;\n"
812 " AdvAutonomous on;\n"
813 "%s"
814 "%s%s%s"
815 " };\n",
816 nvram_safe_get("lan_ifname"),
817 mtu ? " AdvLinkMTU " : "", mtu ? : "", mtu ? ";\n" : "",
818 prefix,
819 (do_6to4 || do_6rd) ? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
820 do_6to4 ? " Base6to4Interface " : "",
821 do_6to4 ? get_wanface() : "",
822 do_6to4 ? ";\n" : "");
824 if (do_dns) {
825 fprintf(f, " RDNSS %s {};\n", ip);
827 else {
828 cnt = write_ipv6_dns_servers(f, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
829 if (cnt == 0 || nvram_get_int("dns_addget"))
830 cnt += write_ipv6_dns_servers(f, (cnt) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
831 if (cnt) fprintf(f, "{};\n");
834 fprintf(f,
835 "};\n"); // close "interface" section
836 fclose(f);
838 // Start radvd
839 argc = 1;
840 if (nvram_get_int("debug_ipv6")) {
841 argv[argc++] = "-d";
842 argv[argc++] = "10";
844 argv[argc] = NULL;
845 _eval(argv, NULL, 0, &pid);
847 if (!nvram_contains_word("debug_norestart", "radvd")) {
848 pid_radvd = -2;
853 void stop_radvd(void)
855 if (getpid() != 1) {
856 stop_service("radvd");
857 return;
860 pid_radvd = -1;
861 killall_tk("radvd");
864 void start_ipv6(void)
866 int service;
868 service = get_ipv6_service();
869 enable_ip6_forward();
871 // Check if turned on
872 switch (service) {
873 case IPV6_NATIVE:
874 case IPV6_6IN4:
875 case IPV6_MANUAL:
876 add_ip6_lanaddr();
877 break;
878 case IPV6_NATIVE_DHCP:
879 case IPV6_ANYCAST_6TO4:
880 nvram_set("ipv6_rtr_addr", "");
881 nvram_set("ipv6_prefix", "");
882 break;
885 if (service != IPV6_DISABLED) {
886 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
887 accept_ra(nvram_safe_get("lan_ifname"));
891 void stop_ipv6(void)
893 stop_ipv6_tunnel();
894 stop_dhcp6c();
895 eval("ip", "-6", "addr", "flush", "scope", "global");
898 #endif
900 // -----------------------------------------------------------------------------
902 void start_upnp(void)
904 if (getpid() != 1) {
905 start_service("upnp");
906 return;
909 if (get_wan_proto() == WP_DISABLED) return;
911 int enable;
912 FILE *f;
913 int upnp_port;
915 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
916 mkdir("/etc/upnp", 0777);
917 if (f_exists("/etc/upnp/config.alt")) {
918 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
920 else {
921 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
922 upnp_port = nvram_get_int("upnp_port");
923 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
926 fprintf(f,
927 "ext_ifname=%s\n"
928 "port=%d\n"
929 "enable_upnp=%s\n"
930 "enable_natpmp=%s\n"
931 "secure_mode=%s\n"
932 "upnp_forward_chain=upnp\n"
933 "upnp_nat_chain=upnp\n"
934 "notify_interval=%d\n"
935 "system_uptime=yes\n"
936 "\n"
938 get_wanface(),
939 upnp_port,
940 (enable & 1) ? "yes" : "no", // upnp enable
941 (enable & 2) ? "yes" : "no", // natpmp enable
942 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
943 nvram_get_int("upnp_ssdp_interval")
946 if (nvram_get_int("upnp_clean")) {
947 int interval = nvram_get_int("upnp_clean_interval");
948 if (interval < 60) interval = 60;
949 fprintf(f,
950 "clean_ruleset_interval=%d\n"
951 "clean_ruleset_threshold=%d\n",
952 interval,
953 nvram_get_int("upnp_clean_threshold")
956 else
957 fprintf(f,"clean_ruleset_interval=0\n");
959 if (nvram_match("upnp_mnp", "1")) {
960 int https = nvram_get_int("https_enable");
961 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
962 https ? "s" : "", nvram_safe_get("lan_ipaddr"),
963 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
965 else {
966 // Empty parameters are not included into XML service description
967 fprintf(f, "presentation_url=\n");
970 char uuid[45];
971 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
972 fprintf(f, "uuid=%s\n", uuid);
974 #ifdef TCONFIG_VLAN
975 char lanN_ipaddr[] = "lanXX_ipaddr";
976 char lanN_netmask[] = "lanXX_netmask";
977 char upnp_lanN[] = "upnp_lanXX";
978 char br;
980 for(br=0 ; br<4 ; br++) {
981 char bridge[2] = "0";
982 if (br!=0)
983 bridge[0]+=br;
984 else
985 strcpy(bridge, "");
987 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
988 sprintf(lanN_netmask, "lan%s_netmask", bridge);
989 sprintf(upnp_lanN, "upnp_lan%s", bridge);
991 char *lanip = nvram_safe_get(lanN_ipaddr);
992 char *lanmask = nvram_safe_get(lanN_netmask);
993 char *lanlisten = nvram_safe_get(upnp_lanN);
995 if((strcmp(lanlisten,"1")==0) && (strcmp(lanip,"")!=0) && (strcmp(lanip,"0.0.0.0")!=0)) {
996 #else
997 char *lanip = nvram_safe_get("lan_ipaddr");
998 char *lanmask = nvram_safe_get("lan_netmask");
999 #endif
1000 fprintf(f,
1001 "listening_ip=%s/%s\n",
1002 lanip, lanmask);
1003 int ports[4];
1004 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
1005 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
1006 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
1007 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
1008 fprintf(f,
1009 "allow %d-%d %s/%s %d-%d\n",
1010 ports[0], ports[1],
1011 lanip, lanmask,
1012 ports[2], ports[3]
1015 else {
1016 // by default allow only redirection of ports above 1024
1017 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
1019 #ifdef TCONFIG_VLAN
1022 #endif
1024 fappend(f, "/jffs/upnpconfig.custom");
1025 fappend(f, "/etc/upnp/config.custom");
1026 fprintf(f, "%s\n", nvram_safe_get("upnp_custom"));
1027 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
1029 fclose(f);
1031 xstart("miniupnpd", "-f", "/etc/upnp/config");
1037 void stop_upnp(void)
1039 if (getpid() != 1) {
1040 stop_service("upnp");
1041 return;
1044 killall_tk("miniupnpd");
1047 // -----------------------------------------------------------------------------
1049 static pid_t pid_crond = -1;
1051 void start_cron(void)
1053 stop_cron();
1055 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
1056 if (!nvram_contains_word("debug_norestart", "crond")) {
1057 pid_crond = -2;
1061 void stop_cron(void)
1063 pid_crond = -1;
1064 killall_tk("crond");
1067 // -----------------------------------------------------------------------------
1068 #ifdef LINUX26
1070 static pid_t pid_hotplug2 = -1;
1072 void start_hotplug2()
1074 stop_hotplug2();
1076 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
1077 xstart("hotplug2", "--persistent", "--no-coldplug");
1078 // FIXME: Don't remember exactly why I put "sleep" here -
1079 // but it was not for a race with check_services()... - TB
1080 sleep(1);
1082 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
1083 pid_hotplug2 = -2;
1087 void stop_hotplug2(void)
1089 pid_hotplug2 = -1;
1090 killall_tk("hotplug2");
1093 #endif /* LINUX26 */
1094 // -----------------------------------------------------------------------------
1096 // Written by Sparq in 2002/07/16
1097 void start_zebra(void)
1099 #ifdef TCONFIG_ZEBRA
1100 if (getpid() != 1) {
1101 start_service("zebra");
1102 return;
1105 FILE *fp;
1107 char *lan_tx = nvram_safe_get("dr_lan_tx");
1108 char *lan_rx = nvram_safe_get("dr_lan_rx");
1109 #ifdef TCONFIG_VLAN
1110 char *lan1_tx = nvram_safe_get("dr_lan1_tx");
1111 char *lan1_rx = nvram_safe_get("dr_lan1_rx");
1112 char *lan2_tx = nvram_safe_get("dr_lan2_tx");
1113 char *lan2_rx = nvram_safe_get("dr_lan2_rx");
1114 char *lan3_tx = nvram_safe_get("dr_lan3_tx");
1115 char *lan3_rx = nvram_safe_get("dr_lan3_rx");
1116 #endif
1117 char *wan_tx = nvram_safe_get("dr_wan_tx");
1118 char *wan_rx = nvram_safe_get("dr_wan_rx");
1120 #ifdef TCONFIG_VLAN
1121 if ((*lan_tx == '0') && (*lan_rx == '0') &&
1122 (*lan1_tx == '0') && (*lan1_rx == '0') &&
1123 (*lan2_tx == '0') && (*lan2_rx == '0') &&
1124 (*lan3_tx == '0') && (*lan3_rx == '0') &&
1125 (*wan_tx == '0') && (*wan_rx == '0')) {
1126 #else
1127 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
1128 #endif
1129 return;
1132 // empty
1133 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
1134 fclose(fp);
1138 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
1139 char *lan_ifname = nvram_safe_get("lan_ifname");
1140 #ifdef TCONFIG_VLAN
1141 char *lan1_ifname = nvram_safe_get("lan1_ifname");
1142 char *lan2_ifname = nvram_safe_get("lan2_ifname");
1143 char *lan3_ifname = nvram_safe_get("lan3_ifname");
1144 #endif
1145 char *wan_ifname = nvram_safe_get("wan_ifname");
1147 fprintf(fp, "router rip\n");
1148 if(strcmp(lan_ifname,"")!=0)
1149 fprintf(fp, "network %s\n", lan_ifname);
1150 #ifdef TCONFIG_VLAN
1151 if(strcmp(lan1_ifname,"")!=0)
1152 fprintf(fp, "network %s\n", lan1_ifname);
1153 if(strcmp(lan2_ifname,"")!=0)
1154 fprintf(fp, "network %s\n", lan2_ifname);
1155 if(strcmp(lan3_ifname,"")!=0)
1156 fprintf(fp, "network %s\n", lan3_ifname);
1157 #endif
1158 fprintf(fp, "network %s\n", wan_ifname);
1159 fprintf(fp, "redistribute connected\n");
1160 //fprintf(fp, "redistribute static\n");
1162 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
1163 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
1165 if(strcmp(lan_ifname,"")!=0) {
1166 fprintf(fp, "interface %s\n", lan_ifname);
1167 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
1168 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
1170 #ifdef TCONFIG_VLAN
1171 if(strcmp(lan1_ifname,"")!=0) {
1172 fprintf(fp, "interface %s\n", lan1_ifname);
1173 if (*lan1_tx != '0') fprintf(fp, "ip rip send version %s\n", lan1_tx);
1174 if (*lan1_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan1_rx);
1176 if(strcmp(lan2_ifname,"")!=0) {
1177 fprintf(fp, "interface %s\n", lan2_ifname);
1178 if (*lan2_tx != '0') fprintf(fp, "ip rip send version %s\n", lan2_tx);
1179 if (*lan2_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan2_rx);
1181 if(strcmp(lan3_ifname,"")!=0) {
1182 fprintf(fp, "interface %s\n", lan3_ifname);
1183 if (*lan3_tx != '0') fprintf(fp, "ip rip send version %s\n", lan3_tx);
1184 if (*lan3_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan3_rx);
1186 #endif
1187 fprintf(fp, "interface %s\n", wan_ifname);
1188 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
1189 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
1191 fprintf(fp, "router rip\n");
1192 if(strcmp(lan_ifname,"")!=0) {
1193 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
1194 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
1196 #ifdef TCONFIG_VLAN
1197 if(strcmp(lan1_ifname,"")!=0) {
1198 if (*lan1_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan1_ifname);
1199 if (*lan1_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan1_ifname);
1201 if(strcmp(lan2_ifname,"")!=0) {
1202 if (*lan2_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan2_ifname);
1203 if (*lan2_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan2_ifname);
1205 if(strcmp(lan3_ifname,"")!=0) {
1206 if (*lan3_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan3_ifname);
1207 if (*lan3_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan3_ifname);
1209 #endif
1210 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
1211 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
1212 fprintf(fp, "access-list private deny any\n");
1214 //fprintf(fp, "debug rip events\n");
1215 //fprintf(fp, "log file /etc/ripd.log\n");
1216 fclose(fp);
1219 xstart("zebra", "-d");
1220 xstart("ripd", "-d");
1221 #endif
1224 void stop_zebra(void)
1226 #ifdef TCONFIG_ZEBRA
1227 if (getpid() != 1) {
1228 stop_service("zebra");
1229 return;
1232 killall("zebra", SIGTERM);
1233 killall("ripd", SIGTERM);
1235 unlink("/etc/zebra.conf");
1236 unlink("/etc/ripd.conf");
1237 #endif
1240 // -----------------------------------------------------------------------------
1242 void start_syslog(void)
1244 char *argv[16];
1245 int argc;
1246 char *nv;
1247 char *b_opt = "";
1248 char rem[256];
1249 int n;
1250 char s[64];
1251 char cfg[256];
1252 char *rot_siz = "50";
1253 char *rot_keep = "1";
1254 char *log_file_path;
1256 argv[0] = "syslogd";
1257 argc = 1;
1259 if (nvram_match("log_remote", "1")) {
1260 nv = nvram_safe_get("log_remoteip");
1261 if (*nv) {
1262 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
1263 argv[argc++] = "-R";
1264 argv[argc++] = rem;
1268 if (nvram_match("log_file", "1")) {
1269 argv[argc++] = "-L";
1271 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1272 rot_siz = nvram_safe_get("log_file_size");
1274 if (nvram_get_int("log_file_size") > 0) {
1275 rot_keep = nvram_safe_get("log_file_keep");
1278 // log to custom path - shibby
1279 if (nvram_match("log_file_custom", "1")) {
1280 log_file_path = nvram_safe_get("log_file_path");
1281 argv[argc++] = "-s";
1282 argv[argc++] = rot_siz;
1283 argv[argc++] = "-O";
1284 argv[argc++] = log_file_path;
1285 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1286 remove("/var/log/messages");
1287 symlink(log_file_path, "/var/log/messages");
1290 else
1292 /* Read options: rotate_size(kb) num_backups logfilename.
1293 * Ignore these settings and use defaults if the logfile cannot be written to.
1295 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
1296 if ((nv = strchr(cfg, '\n')))
1297 *nv = 0;
1299 if ((nv = strtok(cfg, " \t"))) {
1300 if (isdigit(*nv))
1301 rot_siz = nv;
1304 if ((nv = strtok(NULL, " \t")))
1305 b_opt = nv;
1307 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
1308 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
1309 argv[argc++] = "-O";
1310 argv[argc++] = nv;
1312 else {
1313 rot_siz = "50";
1314 b_opt = "";
1319 if (nvram_match("log_file_custom", "0")) {
1320 argv[argc++] = "-s";
1321 argv[argc++] = rot_siz;
1322 struct stat sb;
1323 if (lstat("/var/log/messages", &sb) != -1)
1324 if (S_ISLNK(sb.st_mode))
1325 remove("/var/log/messages");
1328 if (isdigit(*b_opt)) {
1329 argv[argc++] = "-b";
1330 argv[argc++] = b_opt;
1331 } else
1332 if (nvram_get_int("log_file_size") > 0) {
1333 argv[argc++] = "-b";
1334 argv[argc++] = rot_keep;
1338 if (argc > 1) {
1339 argv[argc] = NULL;
1340 _eval(argv, NULL, 0, NULL);
1342 argv[0] = "klogd";
1343 argv[1] = NULL;
1344 _eval(argv, NULL, 0, NULL);
1346 // used to be available in syslogd -m
1347 n = nvram_get_int("log_mark");
1348 if (n > 0) {
1349 // n is in minutes
1350 if (n < 60)
1351 sprintf(rem, "*/%d * * * *", n);
1352 else if (n < 60 * 24)
1353 sprintf(rem, "0 */%d * * *", n / 60);
1354 else
1355 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1356 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1357 eval("cru", "a", "syslogdmark", s);
1359 else {
1360 eval("cru", "d", "syslogdmark");
1365 void stop_syslog(void)
1367 killall("klogd", SIGTERM);
1368 killall("syslogd", SIGTERM);
1371 // -----------------------------------------------------------------------------
1373 static pid_t pid_igmp = -1;
1375 void start_igmp_proxy(void)
1377 FILE *fp;
1379 pid_igmp = -1;
1380 if (nvram_match("multicast_pass", "1")) {
1381 if (get_wan_proto() == WP_DISABLED)
1382 return;
1384 if (f_exists("/etc/igmp.alt")) {
1385 eval("igmpproxy", "/etc/igmp.alt");
1387 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1388 fprintf(fp,
1389 "quickleave\n"
1390 "phyint %s upstream\n"
1391 "\taltnet %s\n",
1392 // "phyint %s downstream ratelimit 0\n",
1393 // get_wanface(),
1394 nvram_safe_get("wan_ifname"),
1395 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1396 // nvram_safe_get("lan_ifname"));
1398 #ifdef TCONFIG_VLAN
1399 char lanN_ifname[] = "lanXX_ifname";
1400 char multicast_lanN[] = "multicast_lanXX";
1401 char br;
1403 for(br=0 ; br<4 ; br++) {
1404 char bridge[2] = "0";
1405 if (br!=0)
1406 bridge[0]+=br;
1407 else
1408 strcpy(bridge, "");
1410 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1411 sprintf(multicast_lanN, "multicast_lan%s", bridge);
1413 if((strcmp(nvram_safe_get(multicast_lanN),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname),"")!=0)) {
1414 fprintf(fp,
1415 "phyint %s downstream ratelimit 0\n",
1416 nvram_safe_get(lanN_ifname));
1419 #else
1420 fprintf(fp,
1421 "phyint %s downstream ratelimit 0\n",
1422 nvram_safe_get("lan_ifname"));
1423 #endif
1424 fclose(fp);
1425 eval("igmpproxy", "/etc/igmp.conf");
1427 else {
1428 return;
1430 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1431 pid_igmp = -2;
1436 void stop_igmp_proxy(void)
1438 pid_igmp = -1;
1439 killall_tk("igmpproxy");
1442 // -----------------------------------------------------------------------------
1444 void start_udpxy(void)
1446 if (nvram_match("udpxy_enable", "1")) {
1447 if (get_wan_proto() == WP_DISABLED)
1448 return;
1449 eval("udpxy", (nvram_get_int("udpxy_stats") ? "-S" : ""), "-p", nvram_safe_get("udpxy_port"), "-c", nvram_safe_get("udpxy_clients"), "-m", nvram_safe_get("wan_ifname") );
1453 void stop_udpxy(void)
1455 killall_tk("udpxy");
1458 // -----------------------------------------------------------------------------
1460 #ifdef TCONFIG_NOCAT
1462 static pid_t pid_splashd = -1;
1463 void start_splashd(void)
1465 pid_splashd = -1;
1466 start_nocat();
1467 if (!nvram_contains_word("debug_norestart", "splashd")) {
1468 pid_splashd = -2;
1472 void stop_splashd(void)
1474 pid_splashd = -1;
1475 stop_nocat();
1476 start_wan(BOOT);
1478 #endif
1480 // -----------------------------------------------------------------------------
1482 void set_tz(void)
1484 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1487 void start_ntpc(void)
1489 set_tz();
1491 stop_ntpc();
1493 if (nvram_get_int("ntp_updates") >= 0) {
1494 xstart("ntpsync", "--init");
1498 void stop_ntpc(void)
1500 killall("ntpsync", SIGTERM);
1503 // -----------------------------------------------------------------------------
1505 static void stop_rstats(void)
1507 int n, m;
1508 int pid;
1509 int pidz;
1510 int ppidz;
1511 int w = 0;
1513 n = 60;
1514 m = 15;
1515 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1516 w = 1;
1517 pidz = pidof("gzip");
1518 if (pidz < 1) pidz = pidof("cp");
1519 ppidz = ppid(ppid(pidz));
1520 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1521 syslog(LOG_DEBUG, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1522 --m;
1523 } else {
1524 kill(pid, SIGTERM);
1526 sleep(1);
1528 if ((w == 1) && (n > 0))
1529 syslog(LOG_DEBUG, "rstats stopped.\n");
1532 static void start_rstats(int new)
1534 if (nvram_match("rstats_enable", "1")) {
1535 stop_rstats();
1536 if (new) {
1537 syslog(LOG_DEBUG, "starting rstats (new datafile).\n");
1538 xstart("rstats", "--new");
1539 } else {
1540 syslog(LOG_DEBUG, "starting rstats.\n");
1541 xstart("rstats");
1546 static void stop_cstats(void)
1548 int n, m;
1549 int pid;
1550 int pidz;
1551 int ppidz;
1552 int w = 0;
1554 n = 60;
1555 m = 15;
1556 while ((n-- > 0) && ((pid = pidof("cstats")) > 0)) {
1557 w = 1;
1558 pidz = pidof("gzip");
1559 if (pidz < 1) pidz = pidof("cp");
1560 ppidz = ppid(ppid(pidz));
1561 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1562 syslog(LOG_DEBUG, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1563 --m;
1564 } else {
1565 kill(pid, SIGTERM);
1567 sleep(1);
1569 if ((w == 1) && (n > 0))
1570 syslog(LOG_DEBUG, "cstats stopped.\n");
1573 static void start_cstats(int new)
1575 if (nvram_match("cstats_enable", "1")) {
1576 stop_cstats();
1577 if (new) {
1578 syslog(LOG_DEBUG, "starting cstats (new datafile).\n");
1579 xstart("cstats", "--new");
1580 } else {
1581 syslog(LOG_DEBUG, "starting cstats.\n");
1582 xstart("cstats");
1587 // -----------------------------------------------------------------------------
1589 // !!TB - FTP Server
1591 #ifdef TCONFIG_FTP
1592 static char *get_full_storage_path(char *val)
1594 static char buf[128];
1595 int len;
1597 if (val[0] == '/')
1598 len = sprintf(buf, "%s", val);
1599 else
1600 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1602 if (len > 1 && buf[len - 1] == '/')
1603 buf[len - 1] = 0;
1605 return buf;
1608 static char *nvram_storage_path(char *var)
1610 char *val = nvram_safe_get(var);
1611 return get_full_storage_path(val);
1614 char vsftpd_conf[] = "/etc/vsftpd.conf";
1615 char vsftpd_users[] = "/etc/vsftpd.users";
1616 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1618 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1620 static void start_ftpd(void)
1622 char tmp[256];
1623 FILE *fp, *f;
1624 char *buf;
1625 char *p, *q;
1626 char *user, *pass, *rights, *root_dir;
1627 int i;
1629 if (getpid() != 1) {
1630 start_service("ftpd");
1631 return;
1634 if (!nvram_get_int("ftp_enable")) return;
1636 mkdir_if_none(vsftpd_users);
1637 mkdir_if_none("/var/run/vsftpd");
1639 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1640 return;
1642 if (nvram_get_int("ftp_super"))
1644 /* rights */
1645 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1646 if ((f = fopen(tmp, "w")))
1648 fprintf(f,
1649 "dirlist_enable=yes\n"
1650 "write_enable=yes\n"
1651 "download_enable=yes\n");
1652 fclose(f);
1656 #ifdef TCONFIG_SAMBASRV
1657 if (nvram_match("smbd_cset", "utf8"))
1658 fprintf(fp, "utf8=yes\n");
1659 #endif
1661 if (nvram_invmatch("ftp_anonymous", "0"))
1663 fprintf(fp,
1664 "anon_allow_writable_root=yes\n"
1665 "anon_world_readable_only=no\n"
1666 "anon_umask=022\n");
1668 /* rights */
1669 sprintf(tmp, "%s/ftp", vsftpd_users);
1670 if ((f = fopen(tmp, "w")))
1672 if (nvram_match("ftp_dirlist", "0"))
1673 fprintf(f, "dirlist_enable=yes\n");
1674 if (nvram_match("ftp_anonymous", "1") ||
1675 nvram_match("ftp_anonymous", "3"))
1676 fprintf(f, "write_enable=yes\n");
1677 if (nvram_match("ftp_anonymous", "1") ||
1678 nvram_match("ftp_anonymous", "2"))
1679 fprintf(f, "download_enable=yes\n");
1680 fclose(f);
1682 if (nvram_match("ftp_anonymous", "1") ||
1683 nvram_match("ftp_anonymous", "3"))
1684 fprintf(fp,
1685 "anon_upload_enable=yes\n"
1686 "anon_mkdir_write_enable=yes\n"
1687 "anon_other_write_enable=yes\n");
1688 } else {
1689 fprintf(fp, "anonymous_enable=no\n");
1692 fprintf(fp,
1693 "dirmessage_enable=yes\n"
1694 "download_enable=no\n"
1695 "dirlist_enable=no\n"
1696 "hide_ids=yes\n"
1697 "syslog_enable=yes\n"
1698 "local_enable=yes\n"
1699 "local_umask=022\n"
1700 "chmod_enable=no\n"
1701 "chroot_local_user=yes\n"
1702 "check_shell=no\n"
1703 "log_ftp_protocol=%s\n"
1704 "user_config_dir=%s\n"
1705 "passwd_file=%s\n"
1706 "listen%s=yes\n"
1707 "listen_port=%s\n"
1708 "background=yes\n"
1709 "isolate=no\n"
1710 "max_clients=%d\n"
1711 "max_per_ip=%d\n"
1712 "max_login_fails=1\n"
1713 "idle_session_timeout=%s\n"
1714 "use_sendfile=no\n"
1715 "anon_max_rate=%d\n"
1716 "local_max_rate=%d\n"
1717 "%s\n",
1718 nvram_get_int("log_ftp") ? "yes" : "no",
1719 vsftpd_users, vsftpd_passwd,
1720 #ifdef TCONFIG_IPV6
1721 ipv6_enabled() ? "_ipv6" : "",
1722 #else
1724 #endif
1725 nvram_get("ftp_port") ? : "21",
1726 nvram_get_int("ftp_max"),
1727 nvram_get_int("ftp_ipmax"),
1728 nvram_get("ftp_staytimeout") ? : "300",
1729 nvram_get_int("ftp_anonrate") * 1024,
1730 nvram_get_int("ftp_rate") * 1024,
1731 nvram_safe_get("ftp_custom"));
1733 fclose(fp);
1735 /* prepare passwd file and default users */
1736 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1737 return;
1739 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1740 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1742 fprintf(fp, /* anonymous, admin, nobody */
1743 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1744 "%s:%s:0:0:root:/:/sbin/nologin\n"
1745 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1746 nvram_storage_path("ftp_anonroot"), user,
1747 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1748 MOUNT_ROOT);
1750 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1753 username<password<rights[<root_dir]
1754 rights:
1755 Read/Write
1756 Read Only
1757 View Only
1758 Private
1760 p = buf;
1761 while ((q = strsep(&p, ">")) != NULL) {
1762 i = vstrsep(q, "<", &user, &pass, &rights, &root_dir);
1763 if (i < 3 || i > 4) continue;
1764 if (!user || !pass) continue;
1766 if (i == 3 || !root_dir || !(*root_dir))
1767 root_dir = nvram_safe_get("ftp_pubroot");
1769 /* directory */
1770 if (strncmp(rights, "Private", 7) == 0)
1772 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1773 mkdir_if_none(tmp);
1775 else
1776 sprintf(tmp, "%s", get_full_storage_path(root_dir));
1778 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1779 user, crypt(pass, "$1$"), user, tmp);
1781 /* rights */
1782 sprintf(tmp, "%s/%s", vsftpd_users, user);
1783 if ((f = fopen(tmp, "w")))
1785 tmp[0] = 0;
1786 if (nvram_invmatch("ftp_dirlist", "1"))
1787 strcat(tmp, "dirlist_enable=yes\n");
1788 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1789 strcat(tmp, "download_enable=yes\n");
1790 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1791 strcat(tmp, "write_enable=yes\n");
1793 fputs(tmp, f);
1794 fclose(f);
1797 free(buf);
1800 fclose(fp);
1801 killall("vsftpd", SIGHUP);
1803 /* start vsftpd if it's not already running */
1804 if (pidof("vsftpd") <= 0)
1805 xstart("vsftpd");
1808 static void stop_ftpd(void)
1810 if (getpid() != 1) {
1811 stop_service("ftpd");
1812 return;
1815 killall_tk("vsftpd");
1816 unlink(vsftpd_passwd);
1817 unlink(vsftpd_conf);
1818 eval("rm", "-rf", vsftpd_users);
1820 #endif // TCONFIG_FTP
1822 // -----------------------------------------------------------------------------
1824 // !!TB - Samba
1826 #ifdef TCONFIG_SAMBASRV
1827 static void kill_samba(int sig)
1829 if (sig == SIGTERM) {
1830 killall_tk("smbd");
1831 killall_tk("nmbd");
1833 else {
1834 killall("smbd", sig);
1835 killall("nmbd", sig);
1839 static void start_samba(void)
1841 FILE *fp;
1842 DIR *dir = NULL;
1843 struct dirent *dp;
1844 char nlsmod[15];
1845 int mode;
1846 char *nv;
1848 if (getpid() != 1) {
1849 start_service("smbd");
1850 return;
1853 mode = nvram_get_int("smbd_enable");
1854 if (!mode || !nvram_invmatch("lan_hostname", ""))
1855 return;
1857 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1858 return;
1860 fprintf(fp, "[global]\n"
1861 " interfaces = %s\n"
1862 " bind interfaces only = yes\n"
1863 " workgroup = %s\n"
1864 " netbios name = %s\n"
1865 " server string = %s\n"
1866 " guest account = nobody\n"
1867 " security = user\n"
1868 " %s\n"
1869 " guest ok = %s\n"
1870 " guest only = no\n"
1871 " browseable = yes\n"
1872 " syslog only = yes\n"
1873 " timestamp logs = no\n"
1874 " syslog = 1\n"
1875 " encrypt passwords = yes\n"
1876 " preserve case = yes\n"
1877 " short preserve case = yes\n",
1878 nvram_safe_get("lan_ifname"),
1879 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1880 nvram_safe_get("lan_hostname"),
1881 nvram_get("router_name") ? : "Tomato",
1882 mode == 2 ? "" : "map to guest = Bad User",
1883 mode == 2 ? "no" : "yes" // guest ok
1886 if (nvram_get_int("smbd_wins")) {
1887 nv = nvram_safe_get("wan_wins");
1888 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1889 fprintf(fp, " wins support = yes\n");
1893 if (nvram_get_int("smbd_master")) {
1894 fprintf(fp,
1895 " domain master = yes\n"
1896 " local master = yes\n"
1897 " preferred master = yes\n"
1898 " os level = 65\n");
1901 nv = nvram_safe_get("smbd_cpage");
1902 if (*nv) {
1903 #ifndef TCONFIG_SAMBA3
1904 fprintf(fp, " client code page = %s\n", nv);
1905 #endif
1906 sprintf(nlsmod, "nls_cp%s", nv);
1908 nv = nvram_safe_get("smbd_nlsmod");
1909 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1910 modprobe_r(nv);
1912 modprobe(nlsmod);
1913 nvram_set("smbd_nlsmod", nlsmod);
1916 #ifndef TCONFIG_SAMBA3
1917 if (nvram_match("smbd_cset", "utf8"))
1918 fprintf(fp, " coding system = utf8\n");
1919 else if (nvram_invmatch("smbd_cset", ""))
1920 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1921 #endif
1923 nv = nvram_safe_get("smbd_custom");
1924 /* add socket options unless overriden by the user */
1925 if (strstr(nv, "socket options") == NULL) {
1926 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1928 fprintf(fp, "%s\n\n", nv);
1930 /* configure shares */
1932 char *buf;
1933 char *p, *q;
1934 char *name, *path, *comment, *writeable, *hidden;
1935 int cnt = 0;
1937 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1939 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1941 p = buf;
1942 while ((q = strsep(&p, ">")) != NULL) {
1943 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1944 if (!path || !name) continue;
1946 /* share name */
1947 fprintf(fp, "\n[%s]\n", name);
1949 /* path */
1950 fprintf(fp, " path = %s\n", path);
1952 /* access level */
1953 if (!strcmp(writeable, "1"))
1954 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1955 if (!strcmp(hidden, "1"))
1956 fprintf(fp, " browseable = no\n");
1958 /* comment */
1959 if (comment)
1960 fprintf(fp, " comment = %s\n", comment);
1962 cnt++;
1964 free(buf);
1967 /* Share every mountpoint below MOUNT_ROOT */
1968 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1969 while ((dp = readdir(dir))) {
1970 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1972 /* Only if is a directory and is mounted */
1973 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1974 continue;
1976 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1977 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1978 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1979 if (nvram_match("smbd_autoshare", "3")) // Hidden
1980 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1981 dp->d_name, MOUNT_ROOT, dp->d_name);
1982 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1983 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1985 cnt++;
1989 if (dir) closedir(dir);
1991 if (cnt == 0) {
1992 /* by default share MOUNT_ROOT as read-only */
1993 fprintf(fp, "\n[share]\n"
1994 " path = %s\n"
1995 " writable = no\n",
1996 MOUNT_ROOT);
1999 fclose(fp);
2001 mkdir_if_none("/var/run/samba");
2002 mkdir_if_none("/etc/samba");
2004 /* write smbpasswd */
2005 #ifdef TCONFIG_SAMBA3
2006 eval("smbpasswd", "nobody", "\"\"");
2007 #else
2008 eval("smbpasswd", "-a", "nobody", "\"\"");
2009 #endif
2010 if (mode == 2) {
2011 char *smbd_user;
2012 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
2013 smbd_user = "nas";
2014 #ifdef TCONFIG_SAMBA3
2015 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
2016 #else
2017 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
2018 #endif
2021 kill_samba(SIGHUP);
2022 int ret1 = 0, ret2 = 0;
2023 /* start samba if it's not already running */
2024 if (pidof("nmbd") <= 0)
2025 ret1 = xstart("nmbd", "-D");
2026 if (pidof("smbd") <= 0)
2027 ret2 = xstart("smbd", "-D");
2029 if (ret1 || ret2) kill_samba(SIGTERM);
2032 static void stop_samba(void)
2034 if (getpid() != 1) {
2035 stop_service("smbd");
2036 return;
2039 kill_samba(SIGTERM);
2040 /* clean up */
2041 unlink("/var/log/smb");
2042 unlink("/var/log/nmb");
2043 eval("rm", "-rf", "/var/run/samba");
2045 #endif // TCONFIG_SAMBASRV
2047 #ifdef TCONFIG_MEDIA_SERVER
2048 #define MEDIA_SERVER_APP "minidlna"
2050 static void start_media_server(void)
2052 FILE *f;
2053 int port, pid, https;
2054 char *dbdir;
2055 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
2056 static int once = 1;
2058 if (getpid() != 1) {
2059 start_service("media");
2060 return;
2063 if (nvram_get_int("ms_sas") == 0)
2064 once = 0;
2066 if (nvram_get_int("ms_enable") != 0) {
2067 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
2068 // no forced rescan
2069 argv[3] = NULL;
2071 nvram_unset("ms_rescan");
2073 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
2074 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
2076 else {
2077 if ((f = fopen(argv[2], "w")) != NULL) {
2078 port = nvram_get_int("ms_port");
2079 https = nvram_get_int("https_enable");
2080 dbdir = nvram_safe_get("ms_dbdir");
2081 if (!(*dbdir)) dbdir = NULL;
2082 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
2084 fprintf(f,
2085 "network_interface=%s\n"
2086 "port=%d\n"
2087 "friendly_name=%s\n"
2088 "db_dir=%s/.db\n"
2089 "enable_tivo=%s\n"
2090 "strict_dlna=%s\n"
2091 "presentation_url=http%s://%s:%s/nas-media.asp\n"
2092 "inotify=yes\n"
2093 "notify_interval=600\n"
2094 "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"
2095 "\n",
2096 nvram_safe_get("lan_ifname"),
2097 (port < 0) || (port >= 0xffff) ? 0 : port,
2098 nvram_get("router_name") ? : "Tomato",
2099 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
2100 nvram_get_int("ms_tivo") ? "yes" : "no",
2101 nvram_get_int("ms_stdlna") ? "yes" : "no",
2102 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
2105 // media directories
2106 char *buf, *p, *q;
2107 char *path, *restrict;
2109 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
2110 /* path<restrict[A|V|P|] */
2112 p = buf;
2113 while ((q = strsep(&p, ">")) != NULL) {
2114 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
2115 continue;
2116 fprintf(f, "media_dir=%s%s%s\n",
2117 restrict ? : "", (restrict && *restrict) ? "," : "", path);
2119 free(buf);
2122 fclose(f);
2126 /* start media server if it's not already running */
2127 if (pidof(MEDIA_SERVER_APP) <= 0) {
2128 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
2129 /* If we started the media server successfully, wait 1 sec
2130 * to let it die if it can't open the database file.
2131 * If it's still alive after that, assume it's running and
2132 * disable forced once-after-reboot rescan.
2134 sleep(1);
2135 if (pidof(MEDIA_SERVER_APP) > 0)
2136 once = 0;
2142 static void stop_media_server(void)
2144 if (getpid() != 1) {
2145 stop_service("media");
2146 return;
2149 killall_tk(MEDIA_SERVER_APP);
2151 #endif // TCONFIG_MEDIA_SERVER
2153 #ifdef TCONFIG_USB
2154 static void start_nas_services(void)
2156 if (getpid() != 1) {
2157 start_service("usbapps");
2158 return;
2161 #ifdef TCONFIG_SAMBASRV
2162 start_samba();
2163 #endif
2164 #ifdef TCONFIG_FTP
2165 start_ftpd();
2166 #endif
2167 #ifdef TCONFIG_MEDIA_SERVER
2168 start_media_server();
2169 #endif
2172 static void stop_nas_services(void)
2174 if (getpid() != 1) {
2175 stop_service("usbapps");
2176 return;
2179 #ifdef TCONFIG_MEDIA_SERVER
2180 stop_media_server();
2181 #endif
2182 #ifdef TCONFIG_FTP
2183 stop_ftpd();
2184 #endif
2185 #ifdef TCONFIG_SAMBASRV
2186 stop_samba();
2187 #endif
2190 void restart_nas_services(int stop, int start)
2192 int fd = file_lock("usb");
2193 /* restart all NAS applications */
2194 if (stop)
2195 stop_nas_services();
2196 if (start)
2197 start_nas_services();
2198 file_unlock(fd);
2200 #endif // TCONFIG_USB
2202 // -----------------------------------------------------------------------------
2204 /* -1 = Don't check for this program, it is not expected to be running.
2205 * Other = This program has been started and should be kept running. If no
2206 * process with the name is running, call func to restart it.
2207 * Note: At startup, dnsmasq forks a short-lived child which forks a
2208 * long-lived (grand)child. The parents terminate.
2209 * Many daemons use this technique.
2211 static void _check(pid_t pid, const char *name, void (*func)(void))
2213 if (pid == -1) return;
2215 if (pidof(name) > 0) return;
2217 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
2218 func();
2220 // Force recheck in 500 msec
2221 setitimer(ITIMER_REAL, &pop_tv, NULL);
2224 void check_services(void)
2226 TRACE_PT("keep alive\n");
2228 // Periodically reap any zombies
2229 setitimer(ITIMER_REAL, &zombie_tv, NULL);
2231 #ifdef LINUX26
2232 _check(pid_hotplug2, "hotplug2", start_hotplug2);
2233 #endif
2234 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
2235 _check(pid_crond, "crond", start_cron);
2236 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
2238 // #ifdef TCONFIG_NOCAT
2239 // if (nvram_get_int("NC_enable"))
2240 // _check(&pid_splashd, "splashd", start_splashd);
2241 // #endif
2245 // -----------------------------------------------------------------------------
2247 void start_services(void)
2249 static int once = 1;
2251 if (once) {
2252 once = 0;
2254 if (nvram_get_int("telnetd_eas")) start_telnetd();
2255 if (nvram_get_int("sshd_eas")) start_sshd();
2258 // start_syslog();
2259 start_nas();
2260 start_zebra();
2261 start_dnsmasq();
2262 start_cifs();
2263 start_httpd();
2264 start_cron();
2265 // start_upnp();
2266 start_rstats(0);
2267 start_cstats(0);
2268 start_sched();
2269 #ifdef TCONFIG_PPTPD
2270 start_pptpd();
2271 #endif
2272 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2274 #ifdef TCONFIG_SNMP
2275 start_snmp();
2276 #endif
2278 #ifdef TCONFIG_NOCAT
2279 start_splashd();
2280 #endif
2284 void stop_services(void)
2286 clear_resolv();
2287 // restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2290 #ifdef TCONFIG_NOCAT
2291 stop_splashd();
2292 #endif
2294 #ifdef TCONFIG_SNMP
2295 stop_snmp();
2296 #endif
2298 #ifdef TCONFIG_TOR
2299 stop_tor();
2300 #endif
2302 #ifdef TCONFIG_NFS
2303 stop_nfs();
2304 #endif
2305 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2306 #ifdef TCONFIG_PPTPD
2307 stop_pptpd();
2308 #endif
2309 stop_sched();
2310 stop_rstats();
2311 stop_cstats();
2312 // stop_upnp();
2313 stop_cron();
2314 stop_httpd();
2315 stop_cifs();
2316 stop_dnsmasq();
2317 stop_zebra();
2318 stop_nas();
2319 // stop_syslog();
2322 // -----------------------------------------------------------------------------
2324 /* nvram "action_service" is: "service-action[-modifier]"
2325 * action is something like "stop" or "start" or "restart"
2326 * optional modifier is "c" for the "service" command-line command
2328 void exec_service(void)
2330 const int A_START = 1;
2331 const int A_STOP = 2;
2332 const int A_RESTART = 1|2;
2333 char buffer[128];
2334 char *service;
2335 char *act;
2336 char *next;
2337 char *modifier;
2338 int action, user;
2339 int i;
2341 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
2342 next = buffer;
2344 TOP:
2345 act = strsep(&next, ",");
2346 service = strsep(&act, "-");
2347 if (act == NULL) {
2348 next = NULL;
2349 goto CLEAR;
2351 modifier = act;
2352 strsep(&modifier, "-");
2354 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
2356 if (strcmp(act, "start") == 0) action = A_START;
2357 else if (strcmp(act, "stop") == 0) action = A_STOP;
2358 else if (strcmp(act, "restart") == 0) action = A_RESTART;
2359 else action = 0;
2360 user = (modifier != NULL && *modifier == 'c');
2362 if (strcmp(service, "dhcpc") == 0) {
2363 if (action & A_STOP) stop_dhcpc();
2364 if (action & A_START) start_dhcpc();
2365 goto CLEAR;
2368 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
2369 if (action & A_STOP) stop_dnsmasq();
2370 if (action & A_START) {
2371 dns_to_resolv();
2372 start_dnsmasq();
2374 goto CLEAR;
2377 if (strcmp(service, "firewall") == 0) {
2378 if (action & A_STOP) {
2379 stop_firewall();
2380 stop_igmp_proxy();
2381 stop_udpxy();
2383 if (action & A_START) {
2384 start_firewall();
2385 start_igmp_proxy();
2386 start_udpxy();
2388 goto CLEAR;
2391 if (strcmp(service, "restrict") == 0) {
2392 if (action & A_STOP) {
2393 stop_firewall();
2395 if (action & A_START) {
2396 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2398 start_firewall();
2400 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2401 if (i == 1) {
2402 if (nvram_get_int("rrules_radio") < 0) {
2403 eval("radio", "on");
2407 goto CLEAR;
2410 if (strcmp(service, "arpbind") == 0) {
2411 if (action & A_STOP) stop_arpbind();
2412 if (action & A_START) start_arpbind();
2413 goto CLEAR;
2416 if (strcmp(service, "qos") == 0) {
2417 if (action & A_STOP) {
2418 stop_qos();
2420 stop_firewall(); start_firewall(); // always restarted
2421 if (action & A_START) {
2422 start_qos();
2423 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2425 goto CLEAR;
2428 if (strcmp(service, "qoslimit") == 0) {
2429 if (action & A_STOP) {
2430 stop_qoslimit();
2432 #ifdef TCONFIG_NOCAT
2433 stop_splashd();
2434 #endif
2435 stop_firewall(); start_firewall(); // always restarted
2436 if (action & A_START) {
2437 start_qoslimit();
2439 #ifdef TCONFIG_NOCAT
2440 start_splashd();
2441 #endif
2442 goto CLEAR;
2445 if (strcmp(service, "upnp") == 0) {
2446 if (action & A_STOP) {
2447 stop_upnp();
2449 stop_firewall(); start_firewall(); // always restarted
2450 if (action & A_START) {
2451 start_upnp();
2453 goto CLEAR;
2456 if (strcmp(service, "telnetd") == 0) {
2457 if (action & A_STOP) stop_telnetd();
2458 if (action & A_START) start_telnetd();
2459 goto CLEAR;
2462 if (strcmp(service, "sshd") == 0) {
2463 if (action & A_STOP) stop_sshd();
2464 if (action & A_START) start_sshd();
2465 goto CLEAR;
2468 if (strcmp(service, "httpd") == 0) {
2469 if (action & A_STOP) stop_httpd();
2470 if (action & A_START) start_httpd();
2471 goto CLEAR;
2474 #ifdef TCONFIG_IPV6
2475 if (strcmp(service, "ipv6") == 0) {
2476 if (action & A_STOP) {
2477 stop_dnsmasq();
2478 stop_ipv6();
2480 if (action & A_START) {
2481 start_ipv6();
2482 start_dnsmasq();
2484 goto CLEAR;
2487 if (strncmp(service, "dhcp6", 5) == 0) {
2488 if (action & A_STOP) {
2489 stop_dhcp6c();
2491 if (action & A_START) {
2492 start_dhcp6c();
2494 goto CLEAR;
2496 #endif
2498 if (strcmp(service, "admin") == 0) {
2499 if (action & A_STOP) {
2500 stop_sshd();
2501 stop_telnetd();
2502 stop_httpd();
2504 stop_firewall(); start_firewall(); // always restarted
2505 if (action & A_START) {
2506 start_httpd();
2507 create_passwd();
2508 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2509 if (nvram_match("sshd_eas", "1")) start_sshd();
2511 goto CLEAR;
2514 if (strcmp(service, "ddns") == 0) {
2515 if (action & A_STOP) stop_ddns();
2516 if (action & A_START) start_ddns();
2517 goto CLEAR;
2520 if (strcmp(service, "ntpc") == 0) {
2521 if (action & A_STOP) stop_ntpc();
2522 if (action & A_START) start_ntpc();
2523 goto CLEAR;
2526 if (strcmp(service, "logging") == 0) {
2527 if (action & A_STOP) {
2528 stop_syslog();
2530 if (action & A_START) {
2531 start_syslog();
2533 if (!user) {
2534 // always restarted except from "service" command
2535 stop_cron(); start_cron();
2536 stop_firewall(); start_firewall();
2538 goto CLEAR;
2541 if (strcmp(service, "crond") == 0) {
2542 if (action & A_STOP) {
2543 stop_cron();
2545 if (action & A_START) {
2546 start_cron();
2548 goto CLEAR;
2551 #ifdef LINUX26
2552 if (strncmp(service, "hotplug", 7) == 0) {
2553 if (action & A_STOP) {
2554 stop_hotplug2();
2556 if (action & A_START) {
2557 start_hotplug2(1);
2559 goto CLEAR;
2561 #endif
2563 if (strcmp(service, "upgrade") == 0) {
2564 if (action & A_START) {
2565 #if TOMATO_SL
2566 stop_usbevent();
2567 stop_smbd();
2568 #endif
2569 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2570 stop_jffs2();
2571 // stop_cifs();
2572 stop_zebra();
2573 stop_cron();
2574 stop_ntpc();
2575 stop_upnp();
2576 // stop_dhcpc();
2577 killall("rstats", SIGTERM);
2578 killall("cstats", SIGTERM);
2579 killall("buttons", SIGTERM);
2580 stop_syslog();
2581 remove_storage_main(1); // !!TB - USB Support
2582 stop_usb(); // !!TB - USB Support
2584 goto CLEAR;
2587 #ifdef TCONFIG_CIFS
2588 if (strcmp(service, "cifs") == 0) {
2589 if (action & A_STOP) stop_cifs();
2590 if (action & A_START) start_cifs();
2591 goto CLEAR;
2593 #endif
2595 #ifdef TCONFIG_JFFS2
2596 if (strncmp(service, "jffs", 4) == 0) {
2597 if (action & A_STOP) stop_jffs2();
2598 if (action & A_START) start_jffs2();
2599 goto CLEAR;
2601 #endif
2603 if (strcmp(service, "zebra") == 0) {
2604 if (action & A_STOP) stop_zebra();
2605 if (action & A_START) start_zebra();
2606 goto CLEAR;
2609 if (strcmp(service, "routing") == 0) {
2610 if (action & A_STOP) {
2611 stop_zebra();
2612 do_static_routes(0); // remove old '_saved'
2613 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2614 #ifdef TCONFIG_VLAN
2615 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2616 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2617 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2618 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2619 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2620 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2621 #endif
2623 stop_firewall();
2624 start_firewall();
2625 if (action & A_START) {
2626 do_static_routes(1); // add new
2627 start_zebra();
2628 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2629 #ifdef TCONFIG_VLAN
2630 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2631 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2632 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2633 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2634 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2635 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2636 #endif
2638 goto CLEAR;
2641 if (strcmp(service, "ctnf") == 0) {
2642 if (action & A_START) {
2643 setup_conntrack();
2644 stop_firewall();
2645 start_firewall();
2647 goto CLEAR;
2650 if (strcmp(service, "wan") == 0) {
2651 if (action & A_STOP) {
2652 stop_wan();
2655 if (action & A_START) {
2656 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2657 start_wan(BOOT);
2658 sleep(2);
2659 force_to_dial();
2661 goto CLEAR;
2664 if (strcmp(service, "net") == 0) {
2665 if (action & A_STOP) {
2666 #ifdef TCONFIG_USB
2667 stop_nas_services();
2668 #endif
2669 stop_httpd();
2670 stop_dnsmasq();
2671 stop_nas();
2672 stop_wan();
2673 stop_arpbind();
2674 stop_lan();
2675 stop_vlan();
2677 if (action & A_START) {
2678 start_vlan();
2679 start_lan();
2680 start_wan(BOOT);
2681 start_arpbind();
2682 start_nas();
2683 start_dnsmasq();
2684 start_httpd();
2685 start_wl();
2686 #ifdef TCONFIG_USB
2687 start_nas_services();
2688 #endif
2690 goto CLEAR;
2693 if (strcmp(service, "wireless") == 0) {
2694 if(action & A_STOP) {
2695 stop_wireless();
2697 if(action & A_START) {
2698 start_wireless();
2700 goto CLEAR;
2703 if (strcmp(service, "wl") == 0) {
2704 if(action & A_STOP) {
2705 stop_wireless();
2706 unload_wl();
2708 if(action & A_START) {
2709 load_wl();
2710 start_wireless();
2711 stop_wireless();
2712 start_wireless();
2714 goto CLEAR;
2717 if (strcmp(service, "nas") == 0) {
2718 if (action & A_STOP) {
2719 stop_nas();
2721 if (action & A_START) {
2722 start_nas();
2723 start_wl();
2725 goto CLEAR;
2728 if (strcmp(service, "rstats") == 0) {
2729 if (action & A_STOP) stop_rstats();
2730 if (action & A_START) start_rstats(0);
2731 goto CLEAR;
2734 if (strcmp(service, "rstatsnew") == 0) {
2735 if (action & A_STOP) stop_rstats();
2736 if (action & A_START) start_rstats(1);
2737 goto CLEAR;
2740 if (strcmp(service, "cstats") == 0) {
2741 if (action & A_STOP) stop_cstats();
2742 if (action & A_START) start_cstats(0);
2743 goto CLEAR;
2746 if (strcmp(service, "cstatsnew") == 0) {
2747 if (action & A_STOP) stop_cstats();
2748 if (action & A_START) start_cstats(1);
2749 goto CLEAR;
2752 if (strcmp(service, "sched") == 0) {
2753 if (action & A_STOP) stop_sched();
2754 if (action & A_START) start_sched();
2755 goto CLEAR;
2759 #ifdef TCONFIG_SNMP
2760 if (strcmp(service, "snmp") == 0) {
2761 if (action & A_STOP) stop_snmp();
2762 if (action & A_START) start_snmp();
2763 goto CLEAR;
2765 #endif
2768 #ifdef TCONFIG_USB
2769 // !!TB - USB Support
2770 if (strcmp(service, "usb") == 0) {
2771 if (action & A_STOP) stop_usb();
2772 if (action & A_START) {
2773 start_usb();
2774 // restart Samba and ftp since they may be killed by stop_usb()
2775 restart_nas_services(0, 1);
2776 // remount all partitions by simulating hotplug event
2777 add_remove_usbhost("-1", 1);
2779 goto CLEAR;
2782 if (strcmp(service, "usbapps") == 0) {
2783 if (action & A_STOP) stop_nas_services();
2784 if (action & A_START) start_nas_services();
2785 goto CLEAR;
2787 #endif
2789 #ifdef TCONFIG_FTP
2790 // !!TB - FTP Server
2791 if (strcmp(service, "ftpd") == 0) {
2792 if (action & A_STOP) stop_ftpd();
2793 setup_conntrack();
2794 stop_firewall();
2795 start_firewall();
2796 if (action & A_START) start_ftpd();
2797 goto CLEAR;
2799 #endif
2801 #ifdef TCONFIG_MEDIA_SERVER
2802 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2803 if (action & A_STOP) stop_media_server();
2804 if (action & A_START) start_media_server();
2805 goto CLEAR;
2807 #endif
2809 #ifdef TCONFIG_SAMBASRV
2810 // !!TB - Samba
2811 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2812 if (action & A_STOP) stop_samba();
2813 if (action & A_START) {
2814 create_passwd();
2815 stop_dnsmasq();
2816 start_dnsmasq();
2817 start_samba();
2819 goto CLEAR;
2821 #endif
2823 #ifdef TCONFIG_OPENVPN
2824 if (strncmp(service, "vpnclient", 9) == 0) {
2825 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2826 if (action & A_START) start_vpnclient(atoi(&service[9]));
2827 goto CLEAR;
2830 if (strncmp(service, "vpnserver", 9) == 0) {
2831 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2832 if (action & A_START) start_vpnserver(atoi(&service[9]));
2833 goto CLEAR;
2835 #endif
2837 #ifdef TCONFIG_NOCAT
2838 if (strcmp(service, "splashd") == 0) {
2839 if (action & A_STOP) stop_splashd();
2840 if (action & A_START) start_splashd();
2841 goto CLEAR;
2843 #endif
2845 #ifdef TCONFIG_PPTPD
2846 if (strcmp(service, "pptpd") == 0) {
2847 if (action & A_STOP) stop_pptpd();
2848 if (action & A_START) start_pptpd();
2849 goto CLEAR;
2851 #endif
2853 #ifdef TCONFIG_USERPPTP
2854 if (strcmp(service, "pptpclient") == 0) {
2855 if (action & A_STOP) stop_pptp_client();
2856 if (action & A_START) start_pptp_client();
2857 if (action & (A_START | A_STOP))
2859 stop_dnsmasq();
2860 dns_to_resolv();
2861 start_dnsmasq();
2862 if ((action & A_START) == 0)
2863 clear_pptp_route();
2865 goto CLEAR;
2867 #endif
2869 CLEAR:
2870 if (next) goto TOP;
2872 // some functions check action_service and must be cleared at end -- zzz
2873 nvram_set("action_service", "");
2875 // Force recheck in 500 msec
2876 setitimer(ITIMER_REAL, &pop_tv, NULL);
2879 static void do_service(const char *name, const char *action, int user)
2881 int n;
2882 char s[64];
2884 n = 150;
2885 while (!nvram_match("action_service", "")) {
2886 if (user) {
2887 putchar('*');
2888 fflush(stdout);
2890 else if (--n < 0) break;
2891 usleep(100 * 1000);
2894 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2895 nvram_set("action_service", s);
2897 if (nvram_match("debug_rc_svc", "1")) {
2898 nvram_unset("debug_rc_svc");
2899 exec_service();
2900 } else {
2901 kill(1, SIGUSR1);
2904 n = 150;
2905 while (nvram_match("action_service", s)) {
2906 if (user) {
2907 putchar('.');
2908 fflush(stdout);
2910 else if (--n < 0) {
2911 break;
2913 usleep(100 * 1000);
2917 int service_main(int argc, char *argv[])
2919 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2920 do_service(argv[1], argv[2], 1);
2921 printf("\nDone.\n");
2922 return 0;
2925 void start_service(const char *name)
2927 do_service(name, "start", 0);
2930 void stop_service(const char *name)
2932 do_service(name, "stop", 0);
2936 void restart_service(const char *name)
2938 do_service(name, "restart", 0);