3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
38 #include <arpa/inet.h>
44 #include <sys/mount.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");
73 const char *router_ip
;
77 char *mac
, *ip
, *name
;
92 start_service("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");
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
);
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
);
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")) {
128 "rebind-localhost-ok\n");
129 // allow RFC1918 responses for server domain
130 switch (get_wan_proto()) {
132 nv
= nvram_get("pptp_server_ip");
135 nv
= nvram_get("l2tp_server_ip");
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");
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";
166 for(br
=0 ; br
<=3 ; br
++) {
167 char bridge
[2] = "0";
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");
180 router_ip
= nvram_safe_get(lanN_ipaddr
);
181 strlcpy(lan
, router_ip
, sizeof(lan
));
182 if ((p
= strrchr(lan
, '.')) != NULL
) *(p
+ 1) = 0;
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
);
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.
203 strcpy(sdhcp_lease
, "2m");
207 // pass the dns directly
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
);
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
;
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
));
258 if (strcmp(nvram_safe_get(lanN_ifname
),"")!=0)
259 fprintf(f
, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname
));
262 // write static lease entries & create hosts file
264 mkdir_if_none(dmhosts
);
265 snprintf(buf
, sizeof(buf
), "%s/hosts", dmhosts
);
266 if ((hf
= fopen(buf
, "w")) != NULL
) {
267 if (((nv
= nvram_get("wan_hostname")) != NULL
) && (*nv
))
268 fprintf(hf
, "%s %s\n", router_ip
, nv
);
269 #ifdef TCONFIG_SAMBASRV
270 else if (((nv
= nvram_get("lan_hostname")) != NULL
) && (*nv
))
271 fprintf(hf
, "%s %s\n", router_ip
, nv
);
273 p
= (char *)get_wanip();
274 if ((*p
== 0) || strcmp(p
, "0.0.0.0") == 0)
276 fprintf(hf
, "%s wan-ip\n", p
);
278 fprintf(hf
, "%s %s-wan\n", p
, nv
);
281 mkdir_if_none(dmdhcp
);
282 snprintf(buf
, sizeof(buf
), "%s/dhcp-hosts", dmdhcp
);
283 df
= fopen(buf
, "w");
285 // PREVIOUS/OLD FORMAT:
286 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 73 w/ delim
287 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
288 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 103 w/ delim
290 // NEW FORMAT (+static ARP binding flag after hostname):
291 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 75 w/ delim
292 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
293 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 105 w/ delim
295 p
= nvram_safe_get("dhcpd_static");
296 while ((e
= strchr(p
, '>')) != NULL
) {
307 if ((e
= strchr(buf
, '<')) == NULL
) continue;
312 if ((e
= strchr(ip
, '<')) == NULL
) continue;
314 if (strchr(ip
, '.') == NULL
) {
316 if ((ipn
<= 0) || (ipn
> 255)) continue;
317 sprintf(ipbuf
, "%s%d", lan
, ipn
);
321 if (inet_addr(ip
) == INADDR_NONE
) continue;
326 if ((e
= strchr(name
, '<')) != NULL
) {
330 if ((hf
) && (*name
!= 0)) {
331 fprintf(hf
, "%s %s\n", ip
, name
);
334 if ((do_dhcpd_hosts
> 0) && (*mac
!= 0) && (strcmp(mac
, "00:00:00:00:00:00") != 0)) {
336 fprintf(df
, "%s,%s,%s\n", mac
, ip
, sdhcp_lease
);
338 fprintf(f
, "dhcp-host=%s,%s,%s\n", mac
, ip
, sdhcp_lease
);
345 n
= nvram_get_int("dhcpd_lmax");
347 "dhcp-lease-max=%d\n",
349 if (nvram_get_int("dhcpd_auth") >= 0) {
350 fprintf(f
, "dhcp-authoritative\n");
355 #ifdef TCONFIG_OPENVPN
356 write_vpn_dnsmasq_config(f
);
359 fprintf(f
, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
361 fappend(f
, "/etc/dnsmasq.custom");
368 unlink("/etc/resolv.conf");
369 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
372 TRACE_PT("run dnsmasq\n");
374 // Default to some values we like, but allow the user to override them.
375 eval("dnsmasq", "-c", "1500", "--log-async");
377 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
384 void stop_dnsmasq(void)
389 stop_service("dnsmasq");
395 unlink("/etc/resolv.conf");
396 symlink(dmresolv
, "/etc/resolv.conf");
398 killall_tk("dnsmasq");
403 void clear_resolv(void)
405 f_write(dmresolv
, NULL
, 0, 0, 0); // blank
409 static int write_ipv6_dns_servers(FILE *f
, const char *prefix
, char *dns
, const char *suffix
, int once
)
411 char p
[INET6_ADDRSTRLEN
+ 1], *next
= NULL
;
412 struct in6_addr addr
;
415 foreach(p
, dns
, next
) {
416 // verify that this is a valid IPv6 address
417 if (inet_pton(AF_INET6
, p
, &addr
) == 1) {
418 fprintf(f
, "%s%s%s", (once
&& cnt
) ? "" : prefix
, p
, suffix
);
427 void dns_to_resolv(void)
430 const dns_list_t
*dns
;
434 m
= umask(022); // 077 from pppoecd
435 if ((f
= fopen(dmresolv
, "w")) != NULL
) {
436 // Check for VPN DNS entries
437 if (!write_vpn_resolv(f
)) {
439 if (write_ipv6_dns_servers(f
, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
440 write_ipv6_dns_servers(f
, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
442 dns
= get_dns(); // static buffer
443 if (dns
->count
== 0) {
444 // Put a pseudo DNS IP to trigger Connect On Demand
445 if (nvram_match("ppp_demand", "1")) {
446 switch (get_wan_proto()) {
450 fprintf(f
, "nameserver 1.1.1.1\n");
456 for (i
= 0; i
< dns
->count
; i
++) {
457 if (dns
->dns
[i
].port
== 53) { // resolv.conf doesn't allow for an alternate port
458 fprintf(f
, "nameserver %s\n", inet_ntoa(dns
->dns
[i
].addr
));
468 // -----------------------------------------------------------------------------
470 void start_httpd(void)
473 start_service("httpd");
483 void stop_httpd(void)
486 stop_service("httpd");
493 // -----------------------------------------------------------------------------
496 static void add_ip6_lanaddr(void)
498 char ip
[INET6_ADDRSTRLEN
+ 4];
501 p
= ipv6_router_address(NULL
);
503 snprintf(ip
, sizeof(ip
), "%s/%d", p
, nvram_get_int("ipv6_prefix_length") ? : 64);
504 eval("ip", "-6", "addr", "add", ip
, "dev", nvram_safe_get("lan_ifname"));
508 void start_ipv6_tunnel(void)
510 char ip
[INET6_ADDRSTRLEN
+ 4];
511 struct in_addr addr4
;
512 struct in6_addr addr
;
513 const char *wanip
, *mtu
, *tun_dev
;
516 service
= get_ipv6_service();
517 tun_dev
= get_wan6face();
519 mtu
= (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
522 if (service
== IPV6_ANYCAST_6TO4
)
523 snprintf(ip
, sizeof(ip
), "192.88.99.%d", nvram_get_int("ipv6_relay"));
525 strlcpy(ip
, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip
));
526 eval("ip", "tunnel", "add", (char *)tun_dev
, "mode", "sit",
528 "local", (char *)wanip
,
529 "ttl", nvram_safe_get("ipv6_tun_ttl"));
531 eval("ip", "link", "set", (char *)tun_dev
, "mtu", (char *)mtu
, "up");
532 nvram_set("ipv6_ifname", (char *)tun_dev
);
534 if (service
== IPV6_ANYCAST_6TO4
) {
537 memset(&addr
, 0, sizeof(addr
));
538 inet_aton(wanip
, &addr4
);
539 addr
.s6_addr16
[0] = htons(0x2002);
540 ipv6_mapaddr4(&addr
, 16, &addr4
, 0);
541 addr
.s6_addr16
[7] = htons(0x0001);
542 inet_ntop(AF_INET6
, &addr
, ip
, sizeof(ip
));
543 strncat(ip
, "/16", sizeof(ip
));
546 snprintf(ip
, sizeof(ip
), "%s/%d",
547 nvram_safe_get("ipv6_tun_addr"),
548 nvram_get_int("ipv6_tun_addrlen") ? : 64);
550 eval("ip", "addr", "add", ip
, "dev", (char *)tun_dev
);
551 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev
);
554 if (service
== IPV6_ANYCAST_6TO4
)
558 void stop_ipv6_tunnel(void)
560 eval("ip", "tunnel", "del", (char *)get_wan6face());
561 if (get_ipv6_service() == IPV6_ANYCAST_6TO4
) {
562 // get rid of old IPv6 address from lan iface
563 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
568 static pid_t pid_radvd
= -1;
570 void start_radvd(void)
573 char *prefix
, *ip
, *mtu
;
575 char *argv
[] = { "radvd", NULL
, NULL
, NULL
};
576 int pid
, argc
, service
, cnt
;
579 start_service("radvd");
585 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
586 service
= get_ipv6_service();
587 do_6to4
= (service
== IPV6_ANYCAST_6TO4
);
591 case IPV6_NATIVE_DHCP
:
594 case IPV6_ANYCAST_6TO4
:
596 mtu
= (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
599 prefix
= do_6to4
? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
602 if (!(*prefix
)) prefix
= "::";
605 if ((f
= fopen("/etc/radvd.conf", "w")) == NULL
) return;
607 ip
= (char *)ipv6_router_address(NULL
);
608 do_dns
= (*ip
) && nvram_match("dhcpd_dmdns", "1");
613 " IgnoreIfMissing on;\n"
614 " AdvSendAdvert on;\n"
615 " MaxRtrAdvInterval 60;\n"
616 " AdvHomeAgentFlag off;\n"
617 " AdvManagedFlag off;\n"
622 " AdvAutonomous on;\n"
626 nvram_safe_get("lan_ifname"),
627 mtu
? " AdvLinkMTU " : "", mtu
? : "", mtu
? ";\n" : "",
629 do_6to4
? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
630 do_6to4
? " Base6to4Interface " : "",
631 do_6to4
? get_wanface() : "",
632 do_6to4
? ";\n" : "");
635 fprintf(f
, " RDNSS %s {};\n", ip
);
638 cnt
= write_ipv6_dns_servers(f
, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
639 if (cnt
== 0 || nvram_get_int("dns_addget"))
640 cnt
+= write_ipv6_dns_servers(f
, (cnt
) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
641 if (cnt
) fprintf(f
, "{};\n");
645 "};\n"); // close "interface" section
650 if (nvram_get_int("debug_ipv6")) {
655 _eval(argv
, NULL
, 0, &pid
);
657 if (!nvram_contains_word("debug_norestart", "radvd")) {
663 void stop_radvd(void)
666 stop_service("radvd");
674 void start_ipv6(void)
678 service
= get_ipv6_service();
681 // Check if turned on
688 case IPV6_NATIVE_DHCP
:
689 case IPV6_ANYCAST_6TO4
:
690 nvram_set("ipv6_rtr_addr", "");
691 nvram_set("ipv6_prefix", "");
695 if (service
!= IPV6_DISABLED
) {
696 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
697 accept_ra(nvram_safe_get("lan_ifname"));
705 eval("ip", "-6", "addr", "flush", "scope", "global");
710 // -----------------------------------------------------------------------------
712 void start_upnp(void)
715 start_service("upnp");
719 if (get_wan_proto() == WP_DISABLED
) return;
725 if (((enable
= nvram_get_int("upnp_enable")) & 3) != 0) {
726 mkdir("/etc/upnp", 0777);
727 if (f_exists("/etc/upnp/config.alt")) {
728 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
731 if ((f
= fopen("/etc/upnp/config", "w")) != NULL
) {
732 upnp_port
= nvram_get_int("upnp_port");
733 if ((upnp_port
< 0) || (upnp_port
>= 0xFFFF)) upnp_port
= 0;
742 "upnp_forward_chain=upnp\n"
743 "upnp_nat_chain=upnp\n"
744 "notify_interval=%d\n"
745 "system_uptime=yes\n"
750 (enable
& 1) ? "yes" : "no", // upnp enable
751 (enable
& 2) ? "yes" : "no", // natpmp enable
752 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
753 nvram_get_int("upnp_ssdp_interval")
756 if (nvram_get_int("upnp_clean")) {
757 int interval
= nvram_get_int("upnp_clean_interval");
758 if (interval
< 60) interval
= 60;
760 "clean_ruleset_interval=%d\n"
761 "clean_ruleset_threshold=%d\n",
763 nvram_get_int("upnp_clean_threshold")
767 fprintf(f
,"clean_ruleset_interval=0\n");
769 if (nvram_match("upnp_mnp", "1")) {
770 int https
= nvram_get_int("https_enable");
771 fprintf(f
, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
772 https
? "s" : "", nvram_safe_get("lan_ipaddr"),
773 nvram_safe_get(https
? "https_lanport" : "http_lanport"));
776 // Empty parameters are not included into XML service description
777 fprintf(f
, "presentation_url=\n");
781 f_read_string("/proc/sys/kernel/random/uuid", uuid
, sizeof(uuid
));
782 fprintf(f
, "uuid=%s\n", uuid
);
785 char lanN_ipaddr
[] = "lanXX_ipaddr";
786 char lanN_netmask
[] = "lanXX_netmask";
787 char upnp_lanN
[] = "upnp_lanXX";
790 for(br
=0 ; br
<4 ; br
++) {
791 char bridge
[2] = "0";
797 sprintf(lanN_ipaddr
, "lan%s_ipaddr", bridge
);
798 sprintf(lanN_netmask
, "lan%s_netmask", bridge
);
799 sprintf(upnp_lanN
, "upnp_lan%s", bridge
);
801 char *lanip
= nvram_safe_get(lanN_ipaddr
);
802 char *lanmask
= nvram_safe_get(lanN_netmask
);
803 char *lanlisten
= nvram_safe_get(upnp_lanN
);
804 if((strcmp(lanlisten
,"1")==0) && (strcmp(lanip
,"")!=0) && (strcmp(lanip
,"0.0.0.0")!=0)) {
806 char *lanip
= nvram_safe_get("lan_ipaddr");
807 char *lanmask
= nvram_safe_get("lan_netmask");
810 "listening_ip=%s/%s\n",
813 if ((ports
[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
814 (ports
[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
815 (ports
[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
816 (ports
[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
818 "allow %d-%d %s/%s %d-%d\n",
825 // by default allow only redirection of ports above 1024
826 fprintf(f
, "allow 1024-65535 %s/%s 1024-65535\n", lanip
, lanmask
);
833 fappend(f
, "/etc/upnp/config.custom");
834 fprintf(f
, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
837 xstart("miniupnpd", "-f", "/etc/upnp/config");
846 stop_service("upnp");
850 killall_tk("miniupnpd");
853 // -----------------------------------------------------------------------------
855 static pid_t pid_crond
= -1;
857 void start_cron(void)
861 eval("crond", nvram_contains_word("log_events", "crond") ? NULL
: "-l", "9");
862 if (!nvram_contains_word("debug_norestart", "crond")) {
873 // -----------------------------------------------------------------------------
876 static pid_t pid_hotplug2
= -1;
878 void start_hotplug2()
882 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE
, 0);
883 xstart("hotplug2", "--persistent", "--no-coldplug");
884 // FIXME: Don't remember exactly why I put "sleep" here -
885 // but it was not for a race with check_services()... - TB
888 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
893 void stop_hotplug2(void)
896 killall_tk("hotplug2");
900 // -----------------------------------------------------------------------------
902 // Written by Sparq in 2002/07/16
903 void start_zebra(void)
907 start_service("zebra");
913 char *lan_tx
= nvram_safe_get("dr_lan_tx");
914 char *lan_rx
= nvram_safe_get("dr_lan_rx");
916 char *lan1_tx
= nvram_safe_get("dr_lan1_tx");
917 char *lan1_rx
= nvram_safe_get("dr_lan1_rx");
918 char *lan2_tx
= nvram_safe_get("dr_lan2_tx");
919 char *lan2_rx
= nvram_safe_get("dr_lan2_rx");
920 char *lan3_tx
= nvram_safe_get("dr_lan3_tx");
921 char *lan3_rx
= nvram_safe_get("dr_lan3_rx");
923 char *wan_tx
= nvram_safe_get("dr_wan_tx");
924 char *wan_rx
= nvram_safe_get("dr_wan_rx");
927 if ((*lan_tx
== '0') && (*lan_rx
== '0') &&
928 (*lan1_tx
== '0') && (*lan1_rx
== '0') &&
929 (*lan2_tx
== '0') && (*lan2_rx
== '0') &&
930 (*lan3_tx
== '0') && (*lan3_rx
== '0') &&
931 (*wan_tx
== '0') && (*wan_rx
== '0')) {
933 if ((*lan_tx
== '0') && (*lan_rx
== '0') && (*wan_tx
== '0') && (*wan_rx
== '0')) {
939 if ((fp
= fopen("/etc/zebra.conf", "w")) != NULL
) {
944 if ((fp
= fopen("/etc/ripd.conf", "w")) != NULL
) {
945 char *lan_ifname
= nvram_safe_get("lan_ifname");
947 char *lan1_ifname
= nvram_safe_get("lan1_ifname");
948 char *lan2_ifname
= nvram_safe_get("lan2_ifname");
949 char *lan3_ifname
= nvram_safe_get("lan3_ifname");
951 char *wan_ifname
= nvram_safe_get("wan_ifname");
953 fprintf(fp
, "router rip\n");
954 if(strcmp(lan_ifname
,"")!=0)
955 fprintf(fp
, "network %s\n", lan_ifname
);
957 if(strcmp(lan1_ifname
,"")!=0)
958 fprintf(fp
, "network %s\n", lan1_ifname
);
959 if(strcmp(lan2_ifname
,"")!=0)
960 fprintf(fp
, "network %s\n", lan2_ifname
);
961 if(strcmp(lan3_ifname
,"")!=0)
962 fprintf(fp
, "network %s\n", lan3_ifname
);
964 fprintf(fp
, "network %s\n", wan_ifname
);
965 fprintf(fp
, "redistribute connected\n");
966 //fprintf(fp, "redistribute static\n");
968 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
969 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
971 if(strcmp(lan_ifname
,"")!=0) {
972 fprintf(fp
, "interface %s\n", lan_ifname
);
973 if (*lan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan_tx
);
974 if (*lan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan_rx
);
977 if(strcmp(lan1_ifname
,"")!=0) {
978 fprintf(fp
, "interface %s\n", lan1_ifname
);
979 if (*lan1_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan1_tx
);
980 if (*lan1_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan1_rx
);
982 if(strcmp(lan2_ifname
,"")!=0) {
983 fprintf(fp
, "interface %s\n", lan2_ifname
);
984 if (*lan2_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan2_tx
);
985 if (*lan2_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan2_rx
);
987 if(strcmp(lan3_ifname
,"")!=0) {
988 fprintf(fp
, "interface %s\n", lan3_ifname
);
989 if (*lan3_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan3_tx
);
990 if (*lan3_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan3_rx
);
993 fprintf(fp
, "interface %s\n", wan_ifname
);
994 if (*wan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", wan_tx
);
995 if (*wan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", wan_rx
);
997 fprintf(fp
, "router rip\n");
998 if(strcmp(lan_ifname
,"")!=0) {
999 if (*lan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan_ifname
);
1000 if (*lan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan_ifname
);
1003 if(strcmp(lan1_ifname
,"")!=0) {
1004 if (*lan1_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan1_ifname
);
1005 if (*lan1_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan1_ifname
);
1007 if(strcmp(lan2_ifname
,"")!=0) {
1008 if (*lan2_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan2_ifname
);
1009 if (*lan2_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan2_ifname
);
1011 if(strcmp(lan3_ifname
,"")!=0) {
1012 if (*lan3_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan3_ifname
);
1013 if (*lan3_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan3_ifname
);
1016 if (*wan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", wan_ifname
);
1017 if (*wan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", wan_ifname
);
1018 fprintf(fp
, "access-list private deny any\n");
1020 //fprintf(fp, "debug rip events\n");
1021 //fprintf(fp, "log file /etc/ripd.log\n");
1025 xstart("zebra", "-d");
1026 xstart("ripd", "-d");
1030 void stop_zebra(void)
1032 #ifdef TCONFIG_ZEBRA
1033 if (getpid() != 1) {
1034 stop_service("zebra");
1038 killall("zebra", SIGTERM
);
1039 killall("ripd", SIGTERM
);
1041 unlink("/etc/zebra.conf");
1042 unlink("/etc/ripd.conf");
1046 // -----------------------------------------------------------------------------
1048 void start_syslog(void)
1058 char *rot_siz
= "50";
1060 argv
[0] = "syslogd";
1063 if (nvram_match("log_remote", "1")) {
1064 nv
= nvram_safe_get("log_remoteip");
1066 snprintf(rem
, sizeof(rem
), "%s:%s", nv
, nvram_safe_get("log_remoteport"));
1067 argv
[argc
++] = "-R";
1072 if (nvram_match("log_file", "1")) {
1073 argv
[argc
++] = "-L";
1075 /* Read options: rotate_size(kb) num_backups logfilename.
1076 * Ignore these settings and use defaults if the logfile cannot be written to.
1078 if (f_read_string("/etc/syslogd.cfg", cfg
, sizeof(cfg
)) > 0) {
1079 if ((nv
= strchr(cfg
, '\n')))
1082 if ((nv
= strtok(cfg
, " \t"))) {
1087 if ((nv
= strtok(NULL
, " \t")))
1090 if ((nv
= strtok(NULL
, " \t")) && *nv
== '/') {
1091 if (f_write(nv
, cfg
, 0, FW_APPEND
, 0) >= 0) {
1092 argv
[argc
++] = "-O";
1102 argv
[argc
++] = "-s";
1103 argv
[argc
++] = rot_siz
;
1105 if (isdigit(*b_opt
)) {
1106 argv
[argc
++] = "-b";
1107 argv
[argc
++] = b_opt
;
1113 _eval(argv
, NULL
, 0, NULL
);
1117 _eval(argv
, NULL
, 0, NULL
);
1119 // used to be available in syslogd -m
1120 n
= nvram_get_int("log_mark");
1124 sprintf(rem
, "*/%d * * * *", n
);
1125 else if (n
< 60 * 24)
1126 sprintf(rem
, "0 */%d * * *", n
/ 60);
1128 sprintf(rem
, "0 0 */%d * *", n
/ (60 * 24));
1129 sprintf(s
, "%s logger -p syslog.info -- -- MARK --", rem
);
1130 eval("cru", "a", "syslogdmark", s
);
1133 eval("cru", "d", "syslogdmark");
1138 void stop_syslog(void)
1140 killall("klogd", SIGTERM
);
1141 killall("syslogd", SIGTERM
);
1144 // -----------------------------------------------------------------------------
1146 static pid_t pid_igmp
= -1;
1148 void start_igmp_proxy(void)
1153 if (nvram_match("multicast_pass", "1")) {
1154 if (get_wan_proto() == WP_DISABLED
)
1157 if (f_exists("/etc/igmp.alt")) {
1158 eval("igmpproxy", "/etc/igmp.alt");
1160 else if ((fp
= fopen("/etc/igmp.conf", "w")) != NULL
) {
1163 "phyint %s upstream\n"
1165 // "phyint %s downstream ratelimit 0\n",
1167 nvram_safe_get("wan_ifname"),
1168 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1169 // nvram_safe_get("lan_ifname"));
1172 char lanN_ifname
[] = "lanXX_ifname";
1173 char multicast_lanN
[] = "multicast_lanXX";
1176 for(br
=0 ; br
<4 ; br
++) {
1177 char bridge
[2] = "0";
1183 sprintf(lanN_ifname
, "lan%s_ifname", bridge
);
1184 sprintf(multicast_lanN
, "multicast_lan%s", bridge
);
1186 if((strcmp(nvram_safe_get(multicast_lanN
),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname
),"")!=0)) {
1188 "phyint %s downstream ratelimit 0\n",
1189 nvram_safe_get(lanN_ifname
));
1194 "phyint %s downstream ratelimit 0\n",
1195 nvram_safe_get("lan_ifname"));
1198 eval("igmpproxy", "/etc/igmp.conf");
1203 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1209 void stop_igmp_proxy(void)
1212 killall_tk("igmpproxy");
1215 // -----------------------------------------------------------------------------
1217 void start_udpxy(void)
1219 if (nvram_match("udpxy_enable", "1")) {
1220 if (get_wan_proto() == WP_DISABLED
)
1222 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") );
1226 void stop_udpxy(void)
1228 killall_tk("udpxy");
1231 // -----------------------------------------------------------------------------
1235 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE
|FW_NEWLINE
, 0644);
1238 void start_ntpc(void)
1244 if (nvram_get_int("ntp_updates") >= 0) {
1245 xstart("ntpsync", "--init");
1249 void stop_ntpc(void)
1251 killall("ntpsync", SIGTERM
);
1254 // -----------------------------------------------------------------------------
1256 static void stop_rstats(void)
1262 while ((n
-- > 0) && ((pid
= pidof("rstats")) > 0)) {
1263 if (kill(pid
, SIGTERM
) != 0) break;
1268 static void start_rstats(int new)
1270 if (nvram_match("rstats_enable", "1")) {
1272 if (new) xstart("rstats", "--new");
1273 else xstart("rstats");
1277 static void stop_cstats(void)
1283 while ((n
-- > 0) && ((pid
= pidof("cstats")) > 0)) {
1284 if (kill(pid
, SIGTERM
) != 0) break;
1289 static void start_cstats(int new)
1291 if (nvram_match("cstats_enable", "1")) {
1293 if (new) xstart("cstats", "--new");
1294 else xstart("cstats");
1298 // -----------------------------------------------------------------------------
1300 // !!TB - FTP Server
1303 static char *get_full_storage_path(char *val
)
1305 static char buf
[128];
1309 len
= sprintf(buf
, "%s", val
);
1311 len
= sprintf(buf
, "%s/%s", MOUNT_ROOT
, val
);
1313 if (len
> 1 && buf
[len
- 1] == '/')
1319 static char *nvram_storage_path(char *var
)
1321 char *val
= nvram_safe_get(var
);
1322 return get_full_storage_path(val
);
1325 char vsftpd_conf
[] = "/etc/vsftpd.conf";
1326 char vsftpd_users
[] = "/etc/vsftpd.users";
1327 char vsftpd_passwd
[] = "/etc/vsftpd.passwd";
1329 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1331 static void start_ftpd(void)
1337 char *user
, *pass
, *rights
, *root_dir
;
1340 if (getpid() != 1) {
1341 start_service("ftpd");
1345 if (!nvram_get_int("ftp_enable")) return;
1347 mkdir_if_none(vsftpd_users
);
1348 mkdir_if_none("/var/run/vsftpd");
1350 if ((fp
= fopen(vsftpd_conf
, "w")) == NULL
)
1353 if (nvram_get_int("ftp_super"))
1356 sprintf(tmp
, "%s/%s", vsftpd_users
, "admin");
1357 if ((f
= fopen(tmp
, "w")))
1360 "dirlist_enable=yes\n"
1361 "write_enable=yes\n"
1362 "download_enable=yes\n");
1367 #ifdef TCONFIG_SAMBASRV
1368 if (nvram_match("smbd_cset", "utf8"))
1369 fprintf(fp
, "utf8=yes\n");
1372 if (nvram_invmatch("ftp_anonymous", "0"))
1375 "anon_allow_writable_root=yes\n"
1376 "anon_world_readable_only=no\n"
1377 "anon_umask=022\n");
1380 sprintf(tmp
, "%s/ftp", vsftpd_users
);
1381 if ((f
= fopen(tmp
, "w")))
1383 if (nvram_match("ftp_dirlist", "0"))
1384 fprintf(f
, "dirlist_enable=yes\n");
1385 if (nvram_match("ftp_anonymous", "1") ||
1386 nvram_match("ftp_anonymous", "3"))
1387 fprintf(f
, "write_enable=yes\n");
1388 if (nvram_match("ftp_anonymous", "1") ||
1389 nvram_match("ftp_anonymous", "2"))
1390 fprintf(f
, "download_enable=yes\n");
1393 if (nvram_match("ftp_anonymous", "1") ||
1394 nvram_match("ftp_anonymous", "3"))
1396 "anon_upload_enable=yes\n"
1397 "anon_mkdir_write_enable=yes\n"
1398 "anon_other_write_enable=yes\n");
1400 fprintf(fp
, "anonymous_enable=no\n");
1404 "dirmessage_enable=yes\n"
1405 "download_enable=no\n"
1406 "dirlist_enable=no\n"
1408 "syslog_enable=yes\n"
1409 "local_enable=yes\n"
1412 "chroot_local_user=yes\n"
1414 "log_ftp_protocol=%s\n"
1415 "user_config_dir=%s\n"
1423 "max_login_fails=1\n"
1424 "idle_session_timeout=%s\n"
1426 "anon_max_rate=%d\n"
1427 "local_max_rate=%d\n"
1429 nvram_get_int("log_ftp") ? "yes" : "no",
1430 vsftpd_users
, vsftpd_passwd
,
1432 ipv6_enabled() ? "_ipv6" : "",
1436 nvram_get("ftp_port") ? : "21",
1437 nvram_get_int("ftp_max"),
1438 nvram_get_int("ftp_ipmax"),
1439 nvram_get("ftp_staytimeout") ? : "300",
1440 nvram_get_int("ftp_anonrate") * 1024,
1441 nvram_get_int("ftp_rate") * 1024,
1442 nvram_safe_get("ftp_custom"));
1446 /* prepare passwd file and default users */
1447 if ((fp
= fopen(vsftpd_passwd
, "w")) == NULL
)
1450 if (((user
= nvram_get("http_username")) == NULL
) || (*user
== 0)) user
= "admin";
1451 if (((pass
= nvram_get("http_passwd")) == NULL
) || (*pass
== 0)) pass
= "admin";
1453 fprintf(fp
, /* anonymous, admin, nobody */
1454 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1455 "%s:%s:0:0:root:/:/sbin/nologin\n"
1456 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1457 nvram_storage_path("ftp_anonroot"), user
,
1458 nvram_get_int("ftp_super") ? crypt(pass
, "$1$") : "x",
1461 if ((buf
= strdup(nvram_safe_get("ftp_users"))) != NULL
)
1464 username<password<rights[<root_dir]
1472 while ((q
= strsep(&p
, ">")) != NULL
) {
1473 i
= vstrsep(q
, "<", &user
, &pass
, &rights
, &root_dir
);
1474 if (i
< 3 || i
> 4) continue;
1475 if (!user
|| !pass
) continue;
1477 if (i
== 3 || !root_dir
|| !(*root_dir
))
1478 root_dir
= nvram_safe_get("ftp_pubroot");
1481 if (strncmp(rights
, "Private", 7) == 0)
1483 sprintf(tmp
, "%s/%s", nvram_storage_path("ftp_pvtroot"), user
);
1487 sprintf(tmp
, "%s", get_full_storage_path(root_dir
));
1489 fprintf(fp
, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1490 user
, crypt(pass
, "$1$"), user
, tmp
);
1493 sprintf(tmp
, "%s/%s", vsftpd_users
, user
);
1494 if ((f
= fopen(tmp
, "w")))
1497 if (nvram_invmatch("ftp_dirlist", "1"))
1498 strcat(tmp
, "dirlist_enable=yes\n");
1499 if (strstr(rights
, "Read") || !strcmp(rights
, "Private"))
1500 strcat(tmp
, "download_enable=yes\n");
1501 if (strstr(rights
, "Write") || !strncmp(rights
, "Private", 7))
1502 strcat(tmp
, "write_enable=yes\n");
1512 killall("vsftpd", SIGHUP
);
1514 /* start vsftpd if it's not already running */
1515 if (pidof("vsftpd") <= 0)
1519 static void stop_ftpd(void)
1521 if (getpid() != 1) {
1522 stop_service("ftpd");
1526 killall_tk("vsftpd");
1527 unlink(vsftpd_passwd
);
1528 unlink(vsftpd_conf
);
1529 eval("rm", "-rf", vsftpd_users
);
1531 #endif // TCONFIG_FTP
1533 // -----------------------------------------------------------------------------
1537 #ifdef TCONFIG_SAMBASRV
1538 static void kill_samba(int sig
)
1540 if (sig
== SIGTERM
) {
1545 killall("smbd", sig
);
1546 killall("nmbd", sig
);
1550 static void start_samba(void)
1559 if (getpid() != 1) {
1560 start_service("smbd");
1564 mode
= nvram_get_int("smbd_enable");
1565 if (!mode
|| !nvram_invmatch("lan_hostname", ""))
1568 if ((fp
= fopen("/etc/smb.conf", "w")) == NULL
)
1571 fprintf(fp
, "[global]\n"
1572 " interfaces = %s\n"
1573 " bind interfaces only = yes\n"
1575 " netbios name = %s\n"
1576 " server string = %s\n"
1577 " guest account = nobody\n"
1578 " security = user\n"
1581 " guest only = no\n"
1582 " browseable = yes\n"
1583 " syslog only = yes\n"
1584 " timestamp logs = no\n"
1586 " encrypt passwords = yes\n"
1587 " preserve case = yes\n"
1588 " short preserve case = yes\n",
1589 nvram_safe_get("lan_ifname"),
1590 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1591 nvram_safe_get("lan_hostname"),
1592 nvram_get("router_name") ? : "Tomato",
1593 mode
== 2 ? "" : "map to guest = Bad User",
1594 mode
== 2 ? "no" : "yes" // guest ok
1597 if (nvram_get_int("smbd_wins")) {
1598 nv
= nvram_safe_get("wan_wins");
1599 if ((*nv
== 0) || (strcmp(nv
, "0.0.0.0") == 0)) {
1600 fprintf(fp
, " wins support = yes\n");
1604 if (nvram_get_int("smbd_master")) {
1606 " domain master = yes\n"
1607 " local master = yes\n"
1608 " preferred master = yes\n"
1609 " os level = 65\n");
1612 nv
= nvram_safe_get("smbd_cpage");
1614 #ifndef TCONFIG_SAMBA3
1615 fprintf(fp
, " client code page = %s\n", nv
);
1617 sprintf(nlsmod
, "nls_cp%s", nv
);
1619 nv
= nvram_safe_get("smbd_nlsmod");
1620 if ((*nv
) && (strcmp(nv
, nlsmod
) != 0))
1624 nvram_set("smbd_nlsmod", nlsmod
);
1627 #ifndef TCONFIG_SAMBA3
1628 if (nvram_match("smbd_cset", "utf8"))
1629 fprintf(fp
, " coding system = utf8\n");
1630 else if (nvram_invmatch("smbd_cset", ""))
1631 fprintf(fp
, " character set = %s\n", nvram_safe_get("smbd_cset"));
1634 nv
= nvram_safe_get("smbd_custom");
1635 /* add socket options unless overriden by the user */
1636 if (strstr(nv
, "socket options") == NULL
) {
1637 fprintf(fp
, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1639 fprintf(fp
, "%s\n\n", nv
);
1641 /* configure shares */
1645 char *name
, *path
, *comment
, *writeable
, *hidden
;
1648 if ((buf
= strdup(nvram_safe_get("smbd_shares"))) != NULL
)
1650 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1653 while ((q
= strsep(&p
, ">")) != NULL
) {
1654 if (vstrsep(q
, "<", &name
, &path
, &comment
, &writeable
, &hidden
) != 5) continue;
1655 if (!path
|| !name
) continue;
1658 fprintf(fp
, "\n[%s]\n", name
);
1661 fprintf(fp
, " path = %s\n", path
);
1664 if (!strcmp(writeable
, "1"))
1665 fprintf(fp
, " writable = yes\n delete readonly = yes\n force user = root\n");
1666 if (!strcmp(hidden
, "1"))
1667 fprintf(fp
, " browseable = no\n");
1671 fprintf(fp
, " comment = %s\n", comment
);
1678 /* Share every mountpoint below MOUNT_ROOT */
1679 if (nvram_get_int("smbd_autoshare") && (dir
= opendir(MOUNT_ROOT
))) {
1680 while ((dp
= readdir(dir
))) {
1681 if (strcmp(dp
->d_name
, ".") && strcmp(dp
->d_name
, "..")) {
1683 /* Only if is a directory and is mounted */
1684 if (!dir_is_mountpoint(MOUNT_ROOT
, dp
->d_name
))
1687 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1688 fprintf(fp
, "\n[%s]\n path = %s/%s\n comment = %s\n",
1689 dp
->d_name
, MOUNT_ROOT
, dp
->d_name
, dp
->d_name
);
1690 if (nvram_match("smbd_autoshare", "3")) // Hidden
1691 fprintf(fp
, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1692 dp
->d_name
, MOUNT_ROOT
, dp
->d_name
);
1693 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1694 fprintf(fp
, " writable = yes\n delete readonly = yes\n force user = root\n");
1700 if (dir
) closedir(dir
);
1703 /* by default share MOUNT_ROOT as read-only */
1704 fprintf(fp
, "\n[share]\n"
1712 mkdir_if_none("/var/run/samba");
1713 mkdir_if_none("/etc/samba");
1715 /* write smbpasswd */
1716 #ifdef TCONFIG_SAMBA3
1717 eval("smbpasswd", "nobody", "\"\"");
1719 eval("smbpasswd", "-a", "nobody", "\"\"");
1723 if (((smbd_user
= nvram_get("smbd_user")) == NULL
) || (*smbd_user
== 0) || !strcmp(smbd_user
, "root"))
1725 #ifdef TCONFIG_SAMBA3
1726 eval("smbpasswd", smbd_user
, nvram_safe_get("smbd_passwd"));
1728 eval("smbpasswd", "-a", smbd_user
, nvram_safe_get("smbd_passwd"));
1733 int ret1
= 0, ret2
= 0;
1734 /* start samba if it's not already running */
1735 if (pidof("nmbd") <= 0)
1736 ret1
= xstart("nmbd", "-D");
1737 if (pidof("smbd") <= 0)
1738 ret2
= xstart("smbd", "-D");
1740 if (ret1
|| ret2
) kill_samba(SIGTERM
);
1743 static void stop_samba(void)
1745 if (getpid() != 1) {
1746 stop_service("smbd");
1750 kill_samba(SIGTERM
);
1752 unlink("/var/log/smb");
1753 unlink("/var/log/nmb");
1754 eval("rm", "-rf", "/var/run/samba");
1756 #endif // TCONFIG_SAMBASRV
1758 #ifdef TCONFIG_MEDIA_SERVER
1759 #define MEDIA_SERVER_APP "minidlna"
1761 static void start_media_server(void)
1764 int port
, pid
, https
;
1766 char *argv
[] = { MEDIA_SERVER_APP
, "-f", "/etc/"MEDIA_SERVER_APP
".conf", "-R", NULL
};
1767 static int once
= 1;
1769 if (getpid() != 1) {
1770 start_service("media");
1774 if (nvram_get_int("ms_sas") == 0)
1777 if (nvram_get_int("ms_enable") != 0) {
1778 if ((!once
) && (nvram_get_int("ms_rescan") == 0)) {
1782 nvram_unset("ms_rescan");
1784 if (f_exists("/etc/"MEDIA_SERVER_APP
".alt")) {
1785 argv
[2] = "/etc/"MEDIA_SERVER_APP
".alt";
1788 if ((f
= fopen(argv
[2], "w")) != NULL
) {
1789 port
= nvram_get_int("ms_port");
1790 https
= nvram_get_int("https_enable");
1791 dbdir
= nvram_safe_get("ms_dbdir");
1792 if (!(*dbdir
)) dbdir
= NULL
;
1793 mkdir_if_none(dbdir
? : "/var/run/"MEDIA_SERVER_APP
);
1796 "network_interface=%s\n"
1798 "friendly_name=%s\n"
1802 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1804 "notify_interval=600\n"
1805 "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"
1807 nvram_safe_get("lan_ifname"),
1808 (port
< 0) || (port
>= 0xffff) ? 0 : port
,
1809 nvram_get("router_name") ? : "Tomato",
1810 dbdir
? : "/var/run/"MEDIA_SERVER_APP
,
1811 nvram_get_int("ms_tivo") ? "yes" : "no",
1812 nvram_get_int("ms_stdlna") ? "yes" : "no",
1813 https
? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https
? "https_lanport" : "http_lanport")
1816 // media directories
1818 char *path
, *restrict
;
1820 if ((buf
= strdup(nvram_safe_get("ms_dirs"))) != NULL
) {
1821 /* path<restrict[A|V|P|] */
1824 while ((q
= strsep(&p
, ">")) != NULL
) {
1825 if (vstrsep(q
, "<", &path
, &restrict
) < 1 || !path
|| !(*path
))
1827 fprintf(f
, "media_dir=%s%s%s\n",
1828 restrict
? : "", (restrict
&& *restrict
) ? "," : "", path
);
1837 /* start media server if it's not already running */
1838 if (pidof(MEDIA_SERVER_APP
) <= 0) {
1839 if ((_eval(argv
, NULL
, 0, &pid
) == 0) && (once
)) {
1840 /* If we started the media server successfully, wait 1 sec
1841 * to let it die if it can't open the database file.
1842 * If it's still alive after that, assume it's running and
1843 * disable forced once-after-reboot rescan.
1846 if (pidof(MEDIA_SERVER_APP
) > 0)
1853 static void stop_media_server(void)
1855 if (getpid() != 1) {
1856 stop_service("media");
1860 killall_tk(MEDIA_SERVER_APP
);
1862 #endif // TCONFIG_MEDIA_SERVER
1865 static void start_nas_services(void)
1867 if (getpid() != 1) {
1868 start_service("usbapps");
1872 #ifdef TCONFIG_SAMBASRV
1878 #ifdef TCONFIG_MEDIA_SERVER
1879 start_media_server();
1883 static void stop_nas_services(void)
1885 if (getpid() != 1) {
1886 stop_service("usbapps");
1890 #ifdef TCONFIG_MEDIA_SERVER
1891 stop_media_server();
1896 #ifdef TCONFIG_SAMBASRV
1901 void restart_nas_services(int stop
, int start
)
1903 int fd
= file_lock("usb");
1904 /* restart all NAS applications */
1906 stop_nas_services();
1908 start_nas_services();
1911 #endif // TCONFIG_USB
1913 // -----------------------------------------------------------------------------
1915 /* -1 = Don't check for this program, it is not expected to be running.
1916 * Other = This program has been started and should be kept running. If no
1917 * process with the name is running, call func to restart it.
1918 * Note: At startup, dnsmasq forks a short-lived child which forks a
1919 * long-lived (grand)child. The parents terminate.
1920 * Many daemons use this technique.
1922 static void _check(pid_t pid
, const char *name
, void (*func
)(void))
1924 if (pid
== -1) return;
1926 if (pidof(name
) > 0) return;
1928 syslog(LOG_DEBUG
, "%s terminated unexpectedly, restarting.\n", name
);
1931 // Force recheck in 500 msec
1932 setitimer(ITIMER_REAL
, &pop_tv
, NULL
);
1935 void check_services(void)
1937 TRACE_PT("keep alive\n");
1939 // Periodically reap any zombies
1940 setitimer(ITIMER_REAL
, &zombie_tv
, NULL
);
1943 _check(pid_hotplug2
, "hotplug2", start_hotplug2
);
1945 _check(pid_dnsmasq
, "dnsmasq", start_dnsmasq
);
1946 _check(pid_crond
, "crond", start_cron
);
1947 _check(pid_igmp
, "igmpproxy", start_igmp_proxy
);
1949 _check(pid_radvd
, "radvd", start_radvd
);
1953 // -----------------------------------------------------------------------------
1955 void start_services(void)
1957 static int once
= 1;
1962 if (nvram_get_int("telnetd_eas")) start_telnetd();
1963 if (nvram_get_int("sshd_eas")) start_sshd();
1978 /* note: starting radvd here might be too early in case of
1979 * DHCPv6 or 6to4 because we won't have received a prefix and
1980 * so it will disable advertisements. To restart them, we have
1981 * to send radvd a SIGHUP, or restart it.
1985 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
1993 void stop_services(void)
1996 // restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2021 // -----------------------------------------------------------------------------
2023 /* nvram "action_service" is: "service-action[-modifier]"
2024 * action is something like "stop" or "start" or "restart"
2025 * optional modifier is "c" for the "service" command-line command
2027 void exec_service(void)
2029 const int A_START
= 1;
2030 const int A_STOP
= 2;
2031 const int A_RESTART
= 1|2;
2040 strlcpy(buffer
, nvram_safe_get("action_service"), sizeof(buffer
));
2044 act
= strsep(&next
, ",");
2045 service
= strsep(&act
, "-");
2051 strsep(&modifier
, "-");
2053 TRACE_PT("service=%s action=%s modifier=%s\n", service
, act
, modifier
? : "");
2055 if (strcmp(act
, "start") == 0) action
= A_START
;
2056 else if (strcmp(act
, "stop") == 0) action
= A_STOP
;
2057 else if (strcmp(act
, "restart") == 0) action
= A_RESTART
;
2059 user
= (modifier
!= NULL
&& *modifier
== 'c');
2061 if (strcmp(service
, "dhcpc") == 0) {
2062 if (action
& A_STOP
) stop_dhcpc();
2063 if (action
& A_START
) start_dhcpc();
2067 if ((strcmp(service
, "dhcpd") == 0) || (strcmp(service
, "dns") == 0) || (strcmp(service
, "dnsmasq") == 0)) {
2068 if (action
& A_STOP
) stop_dnsmasq();
2069 if (action
& A_START
) {
2076 if (strcmp(service
, "firewall") == 0) {
2077 if (action
& A_STOP
) {
2082 if (action
& A_START
) {
2090 if (strcmp(service
, "bwclimon") == 0) {
2091 if (action
& A_STOP
) stop_bwclimon();
2092 if (action
& A_START
) start_bwclimon();
2096 if (strcmp(service
, "account") == 0) {
2097 if (action
& A_STOP
) stop_account();
2098 if (action
& A_START
) start_account();
2102 if (strcmp(service
, "arpbind") == 0) {
2103 if (action
& A_STOP
) stop_arpbind();
2104 if (action
& A_START
) start_arpbind();
2108 if (strcmp(service
, "restrict") == 0) {
2109 if (action
& A_STOP
) {
2112 if (action
& A_START
) {
2113 i
= nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2117 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2119 if (nvram_get_int("rrules_radio") < 0) {
2120 eval("radio", "on");
2127 if (strcmp(service
, "qos") == 0) {
2128 if (action
& A_STOP
) {
2131 stop_firewall(); start_firewall(); // always restarted
2132 if (action
& A_START
) {
2134 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2139 if (strcmp(service
, "upnp") == 0) {
2140 if (action
& A_STOP
) {
2143 stop_firewall(); start_firewall(); // always restarted
2144 if (action
& A_START
) {
2150 if (strcmp(service
, "telnetd") == 0) {
2151 if (action
& A_STOP
) stop_telnetd();
2152 if (action
& A_START
) start_telnetd();
2156 if (strcmp(service
, "sshd") == 0) {
2157 if (action
& A_STOP
) stop_sshd();
2158 if (action
& A_START
) start_sshd();
2162 if (strcmp(service
, "httpd") == 0) {
2163 if (action
& A_STOP
) stop_httpd();
2164 if (action
& A_START
) start_httpd();
2169 if (strcmp(service
, "ipv6") == 0) {
2170 if (action
& A_STOP
) {
2174 if (action
& A_START
) {
2181 if (strcmp(service
, "radvd") == 0) {
2182 if (action
& A_STOP
) {
2185 if (action
& A_START
) {
2191 if (strncmp(service
, "dhcp6", 5) == 0) {
2192 if (action
& A_STOP
) {
2195 if (action
& A_START
) {
2202 if (strcmp(service
, "admin") == 0) {
2203 if (action
& A_STOP
) {
2208 stop_firewall(); start_firewall(); // always restarted
2209 if (action
& A_START
) {
2212 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2213 if (nvram_match("sshd_eas", "1")) start_sshd();
2218 if (strcmp(service
, "ddns") == 0) {
2219 if (action
& A_STOP
) stop_ddns();
2220 if (action
& A_START
) start_ddns();
2224 if (strcmp(service
, "ntpc") == 0) {
2225 if (action
& A_STOP
) stop_ntpc();
2226 if (action
& A_START
) start_ntpc();
2230 if (strcmp(service
, "logging") == 0) {
2231 if (action
& A_STOP
) {
2234 if (action
& A_START
) {
2238 // always restarted except from "service" command
2239 stop_cron(); start_cron();
2240 stop_firewall(); start_firewall();
2245 if (strcmp(service
, "crond") == 0) {
2246 if (action
& A_STOP
) {
2249 if (action
& A_START
) {
2256 if (strncmp(service
, "hotplug", 7) == 0) {
2257 if (action
& A_STOP
) {
2260 if (action
& A_START
) {
2267 if (strcmp(service
, "upgrade") == 0) {
2268 if (action
& A_START
) {
2273 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2281 killall("rstats", SIGTERM
);
2282 killall("cstats", SIGTERM
);
2283 killall("buttons", SIGTERM
);
2285 remove_storage_main(1); // !!TB - USB Support
2286 stop_usb(); // !!TB - USB Support
2292 if (strcmp(service
, "cifs") == 0) {
2293 if (action
& A_STOP
) stop_cifs();
2294 if (action
& A_START
) start_cifs();
2299 #ifdef TCONFIG_JFFS2
2300 if (strncmp(service
, "jffs", 4) == 0) {
2301 if (action
& A_STOP
) stop_jffs2();
2302 if (action
& A_START
) start_jffs2();
2307 if (strcmp(service
, "zebra") == 0) {
2308 if (action
& A_STOP
) stop_zebra();
2309 if (action
& A_START
) start_zebra();
2313 if (strcmp(service
, "routing") == 0) {
2314 if (action
& A_STOP
) {
2316 do_static_routes(0); // remove old '_saved'
2317 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2319 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2320 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2321 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2322 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2323 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2324 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2329 if (action
& A_START
) {
2330 do_static_routes(1); // add new
2332 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2334 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2335 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2336 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2337 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2338 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2339 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2345 if (strcmp(service
, "ctnf") == 0) {
2346 if (action
& A_START
) {
2354 if (strcmp(service
, "wan") == 0) {
2355 if (action
& A_STOP
) {
2359 if (action
& A_START
) {
2360 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2368 if (strcmp(service
, "net") == 0) {
2369 if (action
& A_STOP
) {
2371 stop_nas_services();
2384 if (action
& A_START
) {
2397 start_nas_services();
2403 if (strcmp(service
, "nas") == 0) {
2404 if (action
& A_STOP
) {
2407 if (action
& A_START
) {
2414 if (strcmp(service
, "rstats") == 0) {
2415 if (action
& A_STOP
) stop_rstats();
2416 if (action
& A_START
) start_rstats(0);
2420 if (strcmp(service
, "rstatsnew") == 0) {
2421 if (action
& A_STOP
) stop_rstats();
2422 if (action
& A_START
) start_rstats(1);
2426 if (strcmp(service
, "cstats") == 0) {
2427 if (action
& A_STOP
) stop_cstats();
2428 if (action
& A_START
) start_cstats(0);
2432 if (strcmp(service
, "cstatsnew") == 0) {
2433 if (action
& A_STOP
) stop_cstats();
2434 if (action
& A_START
) start_cstats(1);
2438 if (strcmp(service
, "sched") == 0) {
2439 if (action
& A_STOP
) stop_sched();
2440 if (action
& A_START
) start_sched();
2446 if (strcmp(service
, "snmp") == 0) {
2447 if (action
& A_STOP
) stop_snmp();
2448 if (action
& A_START
) start_snmp();
2455 // !!TB - USB Support
2456 if (strcmp(service
, "usb") == 0) {
2457 if (action
& A_STOP
) stop_usb();
2458 if (action
& A_START
) {
2460 // restart Samba and ftp since they may be killed by stop_usb()
2461 restart_nas_services(0, 1);
2462 // remount all partitions by simulating hotplug event
2463 add_remove_usbhost("-1", 1);
2468 if (strcmp(service
, "usbapps") == 0) {
2469 if (action
& A_STOP
) stop_nas_services();
2470 if (action
& A_START
) start_nas_services();
2476 // !!TB - FTP Server
2477 if (strcmp(service
, "ftpd") == 0) {
2478 if (action
& A_STOP
) stop_ftpd();
2482 if (action
& A_START
) start_ftpd();
2487 #ifdef TCONFIG_MEDIA_SERVER
2488 if (strcmp(service
, "media") == 0 || strcmp(service
, "dlna") == 0) {
2489 if (action
& A_STOP
) stop_media_server();
2490 if (action
& A_START
) start_media_server();
2495 #ifdef TCONFIG_SAMBASRV
2497 if (strcmp(service
, "samba") == 0 || strcmp(service
, "smbd") == 0) {
2498 if (action
& A_STOP
) stop_samba();
2499 if (action
& A_START
) {
2509 #ifdef TCONFIG_OPENVPN
2510 if (strncmp(service
, "vpnclient", 9) == 0) {
2511 if (action
& A_STOP
) stop_vpnclient(atoi(&service
[9]));
2512 if (action
& A_START
) start_vpnclient(atoi(&service
[9]));
2516 if (strncmp(service
, "vpnserver", 9) == 0) {
2517 if (action
& A_STOP
) stop_vpnserver(atoi(&service
[9]));
2518 if (action
& A_START
) start_vpnserver(atoi(&service
[9]));
2526 // some functions check action_service and must be cleared at end -- zzz
2527 nvram_set("action_service", "");
2529 // Force recheck in 500 msec
2530 setitimer(ITIMER_REAL
, &pop_tv
, NULL
);
2533 static void do_service(const char *name
, const char *action
, int user
)
2539 while (!nvram_match("action_service", "")) {
2544 else if (--n
< 0) break;
2548 snprintf(s
, sizeof(s
), "%s-%s%s", name
, action
, (user
? "-c" : ""));
2549 nvram_set("action_service", s
);
2553 while (nvram_match("action_service", s
)) {
2565 int service_main(int argc
, char *argv
[])
2567 if (argc
!= 3) usage_exit(argv
[0], "<service> <action>");
2568 do_service(argv
[1], argv
[2], 1);
2569 printf("\nDone.\n");
2573 void start_service(const char *name
)
2575 do_service(name
, "start", 0);
2578 void stop_service(const char *name
)
2580 do_service(name
, "stop", 0);
2584 void restart_service(const char *name)
2586 do_service(name, "restart", 0);