1/*
2 * Miscellaneous services
3 *
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: services.c 245450 2011-03-10 02:20:15Z rnuti $
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <signal.h>
25#include <unistd.h>
26#include <errno.h>
27
28#include <bcmnvram.h>
29#include <netconf.h>
30#include <shutils.h>
31#include <rc.h>
32#include <pmon.h>
33
34#define assert(a)
35
36#ifdef __CONFIG_NAT__
37static char
38*make_var(char *prefix, int index, char *name)
39{
40	static char buf[100];
41
42	assert(prefix);
43	assert(name);
44
45	if (index)
46		snprintf(buf, sizeof(buf), "%s%d%s", prefix, index, name);
47	else
48		snprintf(buf, sizeof(buf), "%s%s", prefix, name);
49	return buf;
50}
51int
52start_dhcpd(void)
53{
54	FILE *fp;
55	char name[100];
56	char word[32], *next;
57	char dhcp_conf_file[128];
58	char dhcp_lease_file[128];
59	char dhcp_ifnames[128] = "";
60	int index;
61	char tmp[20];
62	int i = 0;
63	char *lan_ifname = NULL;
64
65	if (nvram_match("router_disable", "1"))
66		return 0;
67
68	/* Setup individual dhcp severs for the bridge and the every unbridged interface */
69	for (i = 0; i < MAX_NO_BRIDGE; i++) {
70		if (!i)
71			snprintf(tmp, sizeof(tmp), "lan_ifname");
72		else
73			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
74
75		lan_ifname = nvram_safe_get(tmp);
76
77		if (!strcmp(lan_ifname, ""))
78			continue;
79
80		snprintf(dhcp_ifnames, sizeof(dhcp_ifnames), "%s %s", dhcp_ifnames, lan_ifname);
81	}
82
83	index = 0;
84	foreach(word, dhcp_ifnames, next) {
85
86		if (strstr(word, "br0"))
87			index = 0;
88		else
89			index = 1;
90
91		/* Skip interface if no valid config block is found */
92		if (index < 0) continue;
93
94		if (nvram_invmatch(make_var("lan", index, "_proto"), "dhcp"))
95			continue;
96
97		dprintf("%s %s %s %s\n",
98			nvram_safe_get(make_var("lan", index, "_ifname")),
99			nvram_safe_get(make_var("dhcp", index, "_start")),
100			nvram_safe_get(make_var("dhcp", index, "_end")),
101			nvram_safe_get(make_var("lan", index, "_lease")));
102
103		/* Touch leases file */
104		sprintf(dhcp_lease_file, "/tmp/udhcpd%d.leases", index);
105		if (!(fp = fopen(dhcp_lease_file, "a"))) {
106			perror(dhcp_lease_file);
107			return errno;
108		}
109		fclose(fp);
110
111		/* Write configuration file based on current information */
112		sprintf(dhcp_conf_file, "/tmp/udhcpd%d.conf", index);
113		if (!(fp = fopen(dhcp_conf_file, "w"))) {
114			perror(dhcp_conf_file);
115			return errno;
116		}
117		fprintf(fp, "pidfile /var/run/udhcpd%d.pid\n", index);
118		fprintf(fp, "start %s\n", nvram_safe_get(make_var("dhcp", index, "_start")));
119		fprintf(fp, "end %s\n", nvram_safe_get(make_var("dhcp", index, "_end")));
120		fprintf(fp, "interface %s\n", word);
121		fprintf(fp, "remaining yes\n");
122		fprintf(fp, "lease_file /tmp/udhcpd%d.leases\n", index);
123		fprintf(fp, "option subnet %s\n",
124			nvram_safe_get(make_var("lan", index, "_netmask")));
125		fprintf(fp, "option router %s\n",
126			nvram_safe_get(make_var("lan", index, "_ipaddr")));
127		fprintf(fp, "option dns %s\n", nvram_safe_get(make_var("lan", index, "_ipaddr")));
128		fprintf(fp, "option lease %s\n", nvram_safe_get(make_var("lan", index, "_lease")));
129		snprintf(name, sizeof(name), "%s_wins",
130			nvram_safe_get(make_var("dhcp", index, "_wins")));
131		if (nvram_invmatch(name, ""))
132			fprintf(fp, "option wins %s\n", nvram_get(name));
133		snprintf(name, sizeof(name), "%s_domain",
134			nvram_safe_get(make_var("dhcp", index, "_domain")));
135		if (nvram_invmatch(name, ""))
136			fprintf(fp, "option domain %s\n", nvram_get(name));
137		fclose(fp);
138
139		eval("udhcpd", dhcp_conf_file);
140		index++;
141	}
142	dprintf("done\n");
143	return 0;
144}
145
146int
147stop_dhcpd(void)
148{
149	char sigusr1[] = "-XX";
150	int ret;
151
152/*
153* Process udhcpd handles two signals - SIGTERM and SIGUSR1
154*
155*  - SIGUSR1 saves all leases in /tmp/udhcpd.leases
156*  - SIGTERM causes the process to be killed
157*
158* The SIGUSR1+SIGTERM behavior is what we like so that all current client
159* leases will be honorred when the dhcpd restarts and all clients can extend
160* their leases and continue their current IP addresses. Otherwise clients
161* would get NAK'd when they try to extend/rebind their leases and they
162* would have to release current IP and to request a new one which causes
163* a no-IP gap in between.
164*/
165	sprintf(sigusr1, "-%d", SIGUSR1);
166	eval("killall", sigusr1, "udhcpd");
167	ret = eval("killall", "udhcpd");
168
169	dprintf("done\n");
170	return ret;
171}
172
173int
174start_dns(void)
175{
176	int ret;
177	FILE *fp;
178	char dns_ifnames[64] = "";
179	char tmp[20];
180	int i = 0;
181	char *lan_ifname = NULL;
182	char dns_cmd[255];
183
184	if (nvram_match("router_disable", "1"))
185		return 0;
186
187	/* Create resolv.conf with empty nameserver list */
188	if (!(fp = fopen("/tmp/resolv.conf", "w"))) {
189		perror("/tmp/resolv.conf");
190		return errno;
191	}
192	fclose(fp);
193
194	/* Setup interface list for the dns relay */
195	for (i = 0; i < MAX_NO_BRIDGE; i++) {
196		if (!i)
197			snprintf(tmp, sizeof(tmp), "lan_ifname");
198		else
199			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
200
201		lan_ifname = nvram_safe_get(tmp);
202
203		if (!strcmp(lan_ifname, ""))
204			continue;
205
206		snprintf(dns_ifnames, sizeof(dns_ifnames), "%s -i %s", dns_ifnames, lan_ifname);
207	}
208
209	/* Start the dns relay */
210	sprintf(dns_cmd, "/usr/sbin/dnsmasq -h -n %s -r /tmp/resolv.conf&", dns_ifnames);
211	ret = system(dns_cmd);
212
213	dprintf("done\n");
214	return ret;
215}
216
217int
218stop_dns(void)
219{
220	int ret = eval("killall", "dnsmasq");
221
222	/* Remove resolv.conf */
223	unlink("/tmp/resolv.conf");
224
225	dprintf("done\n");
226	return ret;
227}
228#endif	/* __CONFIG_NAT__ */
229
230/*
231*/
232#ifdef __CONFIG_IPV6__
233/*****************************************************************************
234*  lanX_ipv6_mode: 0=disable, 1=6to4 Enabled, 2=Native Enabled, 3=6to4+native!
235*  lanX_ipv6_6to4id: 0~65535, used to form tunneling address
236*     2002:wwxx:yyzz:lanX_ipv6_6to4id::/64
237*  lanX_ipv6_dns: v6 DNS IP to be given out by dhcp6s.
238*  lanX_ipv6_prefix: prefix for Native IPv6 LAN support
239*  wanX_ipv6_prefix: prefix for Native IPv6 WAN support.
240*    This will take effect only if at least one LAN has native enabled.
241*****************************************************************************/
242
243#ifdef __CONFIG_DHCPV6S__
244static int
245stop_dhcp6s(void)
246{
247	int ret;
248
249	ret = eval("killall", "dhcp6s");
250
251	dprintf("done\n");
252	return ret;
253}
254
255/*	Start the Stateless DHCPv6 server.
256*	Return > 0: number of interfaces configured and supported by this application.
257*		==0: the application is not started since no action is required.
258*		< 0: Error number
259*/
260static int
261start_dhcp6s(void)
262{
263	FILE *fp;
264	int i, ret, pid;
265	int siMode, siCount;
266	char *pcDNS, *pcPrefix, *pcNMask, acPrefix[64];
267	char *pcIF, acIFName[MAX_NO_BRIDGE][IFNAMSIZ];
268	char *dhcp_conf_file = "/tmp/dhcp6s.conf";
269	char *dhcp_lease_file = "/tmp/server6.leases";
270	char *apCommand[MAX_NO_BRIDGE+4] =
271	{	"dhcp6s", "-c", dhcp_conf_file, NULL,	};
272
273	/* Touch leases file */
274	if (!(fp = fopen(dhcp_lease_file, "a"))) {
275		perror(dhcp_lease_file);
276		return errno;
277	}
278	fclose(fp);
279
280	/* Write configuration file based on current information */
281	if (!(fp = fopen(dhcp_conf_file, "w"))) {
282		perror(dhcp_conf_file);
283		return errno;
284	}
285
286	for (i = 0, siCount = 0; i < MAX_NO_BRIDGE; i++) {
287		siMode = atoi(nvram_safe_get(make_var("lan", i, "_ipv6_mode")));
288		if (siMode == 0)
289			continue;
290
291		pcIF = nvram_get(make_var("lan", i, "_ifname"));
292		pcDNS = nvram_get(make_var("lan", i, "_ipv6_dns"));
293		pcPrefix = nvram_get(make_var("lan", i, "_ipv6_prefix"));
294		if (pcIF == NULL || pcPrefix == NULL || pcDNS == NULL)
295			continue;
296
297		strncpy(acIFName[siCount], pcIF, sizeof(acIFName[0]));
298		apCommand[siCount + 3] = acIFName[siCount];
299
300		strncpy(acPrefix, pcPrefix, sizeof(acPrefix));
301		pcNMask= strchr(acPrefix, '/');
302		if (pcNMask == NULL)
303			pcNMask= "112";
304		else
305			*pcNMask++= 0x00;
306
307		fprintf(fp, "interface %s {\n", pcIF);
308		fprintf(fp, " server-preference %d;\n", 25);
309		fprintf(fp, " option dns_servers %s %s;\n", pcDNS,
310			nvram_safe_get(make_var("lan", i, "_domain")));
311		fprintf(fp, " send information-only;\n"); /* Stateless DHCP */
312		fprintf(fp, " link LAN {\n");
313		fprintf(fp, "  pool {\n");
314		fprintf(fp, "   range %s%x to %s%x/%s;\n",
315			acPrefix, 0x1000, acPrefix, 0x2000, pcNMask);
316		fprintf(fp, "   prefix %s;\n", pcPrefix);
317		fprintf(fp, "  };\n"); /* pool */
318		fprintf(fp, " };\n"); /* link */
319		fprintf(fp, "};\n\n"); /* interface */
320
321		siCount++;
322	}
323
324	fclose(fp);
325
326	if (siCount == 0)
327		return 0;
328
329	apCommand[siCount + 3] = NULL;
330	if ((ret = _eval(apCommand, NULL, 0, &pid) < 0))
331		return ret;
332
333	return siCount;
334}
335#endif /* __CONFIG_DHCPV6S__ */
336
337#ifdef __CONFIG_RADVD__
338/*	Construct the interface section to the configuration file.
339*	Return 0: no configuration is generated for this interface.
340*     1: the configuration is written.
341*/
342static int
343radvdconf_add_if(FILE *fp, int siV6Mode, char *pcIFName, char *pcPrefix,
344	char *pc6to4WANIF, unsigned short uw6to4ID)
345{
346	if ((fp == NULL) || (pcIFName == NULL || *pcIFName == 0) ||
347		(pcPrefix == NULL || *pcPrefix == 0))
348		return 0;
349
350	/* Start of interface section */
351	fprintf(fp, "interface %s {\n", pcIFName);
352	fprintf(fp, " AdvSendAdvert on;\n");
353	fprintf(fp, " MinRtrAdvInterval %d;\n", 4);
354	fprintf(fp, " MaxRtrAdvInterval %d;\n", 10);
355	fprintf(fp, " AdvDefaultPreference low;\n");
356	fprintf(fp, " AdvHomeAgentFlag off;\n");
357	fprintf(fp, " AdvOtherConfigFlag on;\n");
358
359	/* Check to advertize Network Prefix */
360	if (siV6Mode & IPV6_NATIVE_ENABLED) {
361		fprintf(fp, " prefix %s {\n", pcPrefix);
362		fprintf(fp, "  AdvOnLink on;\n");
363		fprintf(fp, "  AdvAutonomous on;\n");
364		fprintf(fp, " };\n");
365	}
366
367	/* Check to advertize 6to4 prefix */
368	if ((siV6Mode & IPV6_6TO4_ENABLED) && (pc6to4WANIF && *pc6to4WANIF)) {
369		fprintf(fp, " prefix 0:0:0:%x::/64 {\n", uw6to4ID);
370		fprintf(fp, "  AdvOnLink on;\n");
371		fprintf(fp, "  AdvAutonomous on;\n");
372		fprintf(fp, "  AdvRouterAddr off;\n");
373		fprintf(fp, "  Base6to4Interface %s;\n", pc6to4WANIF);
374		fprintf(fp, "  AdvPreferredLifetime %d;\n", 20);
375		fprintf(fp, "  AdvValidLifetime %d;\n", 30);
376		fprintf(fp, " };\n");
377	}
378
379	/* End of interface section */
380	fprintf(fp, "};\n\n");
381	return 1;
382}
383
384static int
385stop_radvd(void)
386{
387	FILE *fp;
388	int ret;
389
390	ret = eval("killall", "radvd");
391	ret = eval("rm", "-f", "/var/run/radvd.pid");
392
393	if ((fp = fopen("/proc/sys/net/ipv6/conf/all/forwarding", "r+"))) {
394		fputc('0', fp);
395		fclose(fp);
396	}
397	return ret;
398}
399
400/*	Start the Router Advertizement Daemon.
401*	Return > 0: number of interfaces configured and supported by this application.
402*		==0: the application is not started since no action is required.
403*		< 0: Error number
404*/
405static int
406start_radvd(void)
407{
408	FILE *fp;
409	char *pcWANIF, *pcWANPrefix;
410	int i, ret, siMode, siCount, siNative, boolRouterEnable;
411	char *radvd_conf_file = "/tmp/radvd.conf";
412
413	if (!(fp = fopen(radvd_conf_file, "w"))) {
414		perror(radvd_conf_file);
415		return errno;
416	}
417
418	boolRouterEnable = nvram_match("router_disable", "0");
419	pcWANIF = nvram_match("wan_proto", "pppoe")?
420		nvram_safe_get("wan_pppoe_ifname"): nvram_safe_get("wan_ifname");
421
422	/* The Router Advertizement for LAN interfaces */
423	for (i = 0, siCount = 0, siNative = 0; i < MAX_NO_BRIDGE; i++) {
424		siMode = atoi(nvram_safe_get(make_var("lan", i, "_ipv6_mode")));
425		if (siMode == 0 || ((siMode == IPV6_6TO4_ENABLED) && (boolRouterEnable == 0)))
426			continue;
427
428		/* The Router Advertizement for LAN interface */
429		if (radvdconf_add_if(fp, siMode, nvram_get(make_var("lan", i, "_ifname")),
430			nvram_get(make_var("lan", i, "_ipv6_prefix")),
431			pcWANIF, /* Use the logical interface for 6to4 */
432			atoi(nvram_safe_get(make_var("lan", i, "_ipv6_6to4id"))))) {
433			if (siMode & IPV6_NATIVE_ENABLED)
434				siNative++;
435			siCount++;
436		}
437	}
438
439	/* The Router Advertizement for WAN interface */
440	if (siNative && boolRouterEnable && (pcWANPrefix = nvram_get("wan_ipv6_prefix"))) {
441		radvdconf_add_if(fp, IPV6_NATIVE_ENABLED,
442			nvram_get("wan_ifname"), /* Use the physical interface */
443			pcWANPrefix, NULL, 0);
444	}
445
446	fclose(fp);
447
448	if (siCount == 0)
449		return 0;
450
451	/*  Enable forwarding as radvd mandates this */
452	if ((fp = fopen("/proc/sys/net/ipv6/conf/all/forwarding", "r+"))) {
453		fputc('1', fp);
454		fclose(fp);
455	}
456
457	if ((ret = eval("radvd", "-C", radvd_conf_file)) < 0)
458		return ret;
459
460	return siCount;
461}
462#endif /* __CONFIG_RADVD__ */
463
464/*	Add routes for IPv6 enabled LAN/WAN interfaces.
465*	Return > 0: number of interfaces configured and supported by this application.
466*		==0: the application is not started since no action is required.
467*		< 0: Error number
468*/
469static int
470ipv6_add_routes_del_addrs(void)
471{
472	int i, ret;
473	int siMode, siCount;
474	char *pcLANIF;
475
476	/* Setup v6 route and clean up unnecessary autoconfigured addresses for LANs */
477	for (i = 0, siCount = 0; i < MAX_NO_BRIDGE; i++) {
478		pcLANIF = nvram_get(make_var("lan", i, "_ifname"));
479		if (pcLANIF == NULL || *pcLANIF == 0x00)
480			continue;
481		siMode = atoi(nvram_safe_get(make_var("lan", i, "_ipv6_mode")));
482		if (siMode == 0)
483			eval("/usr/sbin/ip", "-6", "addr", "flush", "dev", pcLANIF, "scope", "all");
484		else if ((siMode & IPV6_NATIVE_ENABLED)) {
485			ret = eval("/usr/sbin/ip", "-6", "route", "add",
486				nvram_safe_get(make_var("lan", i, "_ipv6_prefix")), "dev",
487				pcLANIF, "metric", "1");
488			siCount++;
489		}
490	}
491
492	/* Setup v6 route and clean up addresses for WAN */
493	{
494		char *pcWANPrefix, *pcWANIF;
495
496		/* Native is not enabled, or router is disabled, or the wan prefix is not set */
497		if (siCount == 0 || nvram_invmatch("router_disable", "0") ||
498			((pcWANPrefix = nvram_get("wan_ipv6_prefix")) == NULL) ||
499			(*pcWANPrefix == 0x00)) {
500			eval("/usr/sbin/ip", "-6", "addr", "flush", "dev",
501				nvram_safe_get("wan_ifname"), "scope", "all");
502		}
503		else {
504			pcWANIF = nvram_match("wan_proto", "pppoe")?
505				nvram_get("wan_pppoe_ifname"): nvram_get("wan_ifname");
506			if (pcWANIF && (*pcWANIF != 0x00))
507				ret = eval("/usr/sbin/ip", "-6", "route", "add",
508					pcWANPrefix, "dev",	pcWANIF, "metric", "1");
509		}
510	}
511
512	return siCount;
513}
514
515int
516stop_ipv6(void)
517{
518	int ret;
519
520#ifdef __CONFIG_RADVD__
521  ret = stop_radvd();
522#endif /* __CONFIG_RADVD__ */
523
524#ifdef __CONFIG_DHCPV6S__
525	ret = stop_dhcp6s();
526#endif /* __CONFIG_DHCPV6S__ */
527
528	/* Flush all v6 routes */
529	ret = eval("/usr/sbin/ip", "-6", "route", "flush");
530
531	return ret;
532}
533
534/*
535*	Return > 0: number of interfaces configured and supported by this application.
536*		==0: the application is not started since no action is required.
537*		< 0: Error number
538*/
539int
540start_ipv6(void)
541{
542	int ret= 0;
543	int siSocket;
544
545	/* Check if IPv6 protocol stack is running */
546	if ((siSocket = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW)) < 0)
547		return 0;
548	close(siSocket);
549
550#ifdef __CONFIG_DHCPV6S__
551  if ((ret = start_dhcp6s()) < 0)
552  	return ret;
553#endif /* __CONFIG_DHCPV6S__ */
554
555#ifdef __CONFIG_RADVD__
556	/* If no interface is configured by radvd than it is done! */
557	if ((ret = start_radvd()) < 0) {
558		stop_dhcp6s();
559		return ret;
560	}
561#endif /* __CONFIG_RADVD__ */
562
563	/* Note that 6to4 routing is done in wan_up()! */
564	return ipv6_add_routes_del_addrs();
565}
566
567int
568is_ipv6_enabled(void)
569{
570	int i, siMode;
571
572	for (i = 0; i < MAX_NO_BRIDGE; i++) {
573		siMode = atoi(nvram_safe_get(make_var("lan", i, "_ipv6_mode")));
574		if (siMode)
575			return TRUE;
576	}
577	return FALSE;
578}
579
580#endif /* __CONFIG_IPV6__ */
581/*
582*/
583
584int
585start_httpd(void)
586{
587	int ret;
588
589	chdir("/www");
590	ret = eval("httpd");
591	chdir("/");
592
593	dprintf("done\n");
594	return ret;
595}
596
597int
598stop_httpd(void)
599{
600	int ret = eval("killall", "httpd");
601
602	dprintf("done\n");
603	return ret;
604}
605
606#ifdef PLC
607/* Run time check for if gigled must be started based on nvram keys */
608static int
609target_uses_gigled(void)
610{
611	return nvram_match("wl0_plc", "1") || nvram_match("wl1_plc", "1");
612}
613
614static int
615start_gigled(void)
616{
617	int ret;
618
619	chdir("/tmp");
620	ret = eval("/usr/sbin/gigled");
621	chdir("/");
622
623	dprintf("done\n");
624	return ret;
625}
626
627static int
628stop_gigled(void)
629{
630	int ret = eval("killall", "gigled");
631
632	dprintf("done\n");
633	return ret;
634}
635#endif
636
637#ifdef __CONFIG_NAT__
638#ifdef __CONFIG_UPNP__
639int
640start_upnp(void)
641{
642	char *wan_ifname;
643	int ret;
644	char var[100], prefix[] = "wanXXXXXXXXXX_";
645
646	if (!nvram_invmatch("upnp_enable", "0"))
647		return 0;
648
649	ret = eval("killall", "-SIGUSR1", "upnp");
650	if (ret != 0) {
651	    snprintf(prefix, sizeof(prefix), "wan%d_", wan_primary_ifunit());
652	    wan_ifname = nvram_match(strcat_r(prefix, "proto", var), "pppoe") ?\
653				nvram_safe_get(strcat_r(prefix, "pppoe_ifname", var)) :\
654				nvram_safe_get(strcat_r(prefix, "ifname", var));
655
656		ret = eval("upnp", "-D", "-W", wan_ifname);
657
658	}
659	dprintf("done\n");
660	return ret;
661}
662
663int
664stop_upnp(void)
665{
666	int ret = 0;
667
668	if (nvram_match("upnp_enable", "0"))
669	    ret = eval("killall", "upnp");
670
671	dprintf("done\n");
672	return ret;
673}
674#endif /* __CONFIG_UPNP__ */
675
676#ifdef	__CONFIG_IGD__
677int
678start_igd(void)
679{
680	int ret = 0;
681
682	if (nvram_match("upnp_enable", "1")) {
683		ret = eval("igd", "-D");
684	}
685
686	return ret;
687}
688
689int
690stop_igd(void)
691{
692	int ret = 0;
693
694	ret = eval("killall", "igd");
695
696	return ret;
697}
698#endif	/* __CONFIG_IGD__ */
699#endif	/* __CONFIG_NAT__ */
700
701
702
703int
704start_nas(void)
705{
706	int ret = eval("nas");;
707
708#ifdef __CONFIG_MEDIA_IPTV__
709
710	pid_t pid;
711	pid_t prev_pid = -1;
712	int found = 0;
713
714	/* Iterate a few times to allow nas to finish daemonizing itself. */
715	do {
716		sleep(1);
717		if ((pid = get_pid_by_name("nas")) <= 0)
718			break;
719		found = (pid == prev_pid) ? found + 1 : 1;
720		prev_pid = pid;
721	} while (found < 3);
722
723	if (found == 3)
724		pmon_register(pid, &start_nas);
725
726#endif /* __CONFIG_MEDIA_IPTV__ */
727
728	return ret;
729}
730
731int
732stop_nas(void)
733{
734	int ret;
735
736#ifdef __CONFIG_MEDIA_IPTV__
737
738	pid_t pid;
739
740	if ((pid = pmon_get_pid(&start_nas)) > 0)
741		pmon_unregister(pid);
742
743#endif /* __CONFIG_MEDIA_IPTV__ */
744
745	ret = eval("killall", "nas");
746
747	return ret;
748}
749
750#ifdef __CONFIG_WAPI__
751int
752start_wapid(void)
753{
754	int ret = eval("wapid");
755
756	return ret;
757}
758
759int
760stop_wapid(void)
761{
762	int ret = eval("killall", "wapid");
763
764	return ret;
765}
766#endif /* __CONFIG_WAPI__ */
767
768#ifdef __CONFIG_WAPI_IAS__
769int
770start_ias(void)
771{
772	char *ias_argv[] = {"ias", "-F", "/etc/AS.conf", "-D", NULL};
773	pid_t pid;
774
775	if (nvram_match("as_mode", "enabled")) {
776		_eval(ias_argv, NULL, 0, &pid);
777	}
778
779	return 0;
780}
781
782int
783stop_ias(void)
784{
785	int ret = 0;
786
787	if (!nvram_match("as_mode", "enabled")) {
788		/* Need add signal handler in as */
789		ret = eval("killall", "ias");
790	}
791
792	return ret;
793}
794#endif /* __CONFIG_WAPI_IAS__ */
795
796int
797start_ntpc(void)
798{
799	char *servers = nvram_safe_get("ntp_server");
800
801	if (strlen(servers)) {
802		char *nas_argv[] = {"ntpclient", "-h", servers, "-i", "3", "-l", "-s", NULL};
803		pid_t pid;
804
805		_eval(nas_argv, NULL, 0, &pid);
806	}
807
808	dprintf("done\n");
809	return 0;
810}
811
812int
813stop_ntpc(void)
814{
815	int ret = eval("killall", "ntpclient");
816
817	dprintf("done\n");
818	return ret;
819}
820
821int
822start_telnet(void)
823{
824	char tmp[20];
825	int i = 0;
826	int ret = 0;
827	char *lan_ifname = NULL;
828
829	for (i = 0; i < MAX_NO_BRIDGE; i++) {
830		if (!i)
831			snprintf(tmp, sizeof(tmp), "lan_ifname");
832		else
833			snprintf(tmp, sizeof(tmp), "lan%x_ifname", i);
834
835		lan_ifname = nvram_safe_get(tmp);
836
837		if (!strcmp(lan_ifname, ""))
838			continue;
839
840		ret = eval("utelnetd", "-d", "-i", lan_ifname);
841	}
842
843	return ret;
844}
845
846int
847stop_telnet(void)
848{
849	int ret;
850	ret = eval("killall", "utelnetd");
851	return ret;
852}
853
854
855int
856start_wps(void)
857{
858	char *wps_argv[] = {"/bin/wps_monitor", NULL};
859	pid_t pid;
860    if ( nvram_match("wps_status", "2") && !nvram_match("wps_start", "pbc") ) /* added for CGI process */
861    {
862        return 0;
863    }
864
865	nvram_set("wps_status", "0");
866	nvram_set("wps_method", "1");
867	nvram_set("wps_config_command", "0");
868	nvram_set("wps_proc_mac", "");
869	nvram_set("wps_proc_status", "0");
870
871	if (nvram_match("wps_restart", "1")) {
872		nvram_set("wps_restart", "0");
873	}
874	else {
875		nvram_set("wps_restart", "0");
876		nvram_set("wps_proc_status", "0");
877	}
878
879	nvram_set("wps_sta_pin", "00000000");
880	nvram_set("wps_currentband", "");
881
882   	eval("killall","wps_monitor");
883   	eval("killall","wps_ap");
884   	eval("killall","wps_enr");
885	_eval(wps_argv, NULL, 0, &pid);
886
887	return 0;
888
889}
890
891int
892stop_wps(void)
893{
894   	int ret = 0;
895
896   	ret = eval("killall","wps_monitor");
897   	ret = eval("rm", "-f", "/tmp/wps_monitor.pid");
898   	ret = eval("killall","wps_ap");
899
900   	return ret;
901
902}
903
904int
905start_bcmupnp(void)
906{
907	int ret;
908
909	if (!nvram_invmatch("upnp_enable", "0"))
910	{
911	    printf("upnp_enable is 0, needn't trigger bcmupnp.\n");
912		return 0;
913	}
914
915    if ( nvram_match("wl0_wps_mode", "disabled") || nvram_match("wps_mode", "disabled") )
916    {
917        printf("WPS is disabled, needn't trigger bcmupnp.\n");
918        return 0;
919    }
920
921    /* Restart upnp properly */
922#if 0
923	ret = eval("killall", "-SIGUSR1", "upnp");
924	if (ret != 0)
925	{
926		ret = eval("upnp", "-D", "-W", nvram_get("wan_ifname"));
927	}
928#endif
929	eval("killall", "upnp");
930	eval("upnp", "-D", "-W", nvram_get("wan_ifname"));
931
932	dprintf("done\n");
933	return ret;
934}
935
936int
937stop_bcmupnp(void)
938{
939	int ret = 0;
940
941	if (nvram_match("upnp_enable", "0"))
942	    ret = eval("killall", "upnp");
943
944	dprintf("done\n");
945	return ret;
946}
947
948#ifdef __CONFIG_IGMP_PROXY__
949void
950start_igmp_proxy(void)
951{
952	/* Start IGMP Proxy in Router mode only */
953	if (!nvram_match("router_disable", "1"))
954		eval("igmp", nvram_get("wan_ifname"));
955	return;
956}
957
958void
959stop_igmp_proxy(void)
960{
961	eval("killall", "igmp");
962	return;
963}
964#endif /* __CONFIG_IGMP_PROXY__ */
965
966#ifdef __CONFIG_LLD2D__
967int start_lltd(void)
968{
969	chdir("/usr/sbin");
970	eval("lld2d", "br0");
971	chdir("/");
972
973	return 0;
974}
975
976int stop_lltd(void)
977{
978	int ret;
979
980	ret = eval("killall", "lld2d");
981
982	return ret;
983}
984#endif /* __CONFIG_LLD2D__ */
985
986int
987start_eapd(void)
988{
989	int ret = eval("/bin/eapd");
990
991	return ret;
992}
993
994int
995stop_eapd(void)
996{
997   	int ret = eval("killall","eapd");
998
999   	return ret;
1000}
1001
1002#if defined(BCM_DCS) || defined(EXT_ACS)
1003int
1004start_acsd(void)
1005{
1006	int ret = eval("/usr/sbin/acsd");
1007
1008	return ret;
1009}
1010
1011int
1012stop_acsd(void)
1013{
1014   	int ret = eval("killall","acsd");
1015
1016   	return ret;
1017}
1018#endif /* BCM_DCS || EXT_ACS */
1019
1020
1021#if defined(PHYMON)
1022int
1023start_phymons(void)
1024{
1025	int ret = eval("/usr/sbin/phymons");
1026
1027	return ret;
1028}
1029
1030int
1031stop_phymons(void)
1032{
1033	int ret = eval("killall", "phymons");
1034
1035	return ret;
1036}
1037#endif /*  PHYMON */
1038
1039#ifdef __CONFIG_SAMBA__
1040int
1041start_samba()
1042{
1043	char *argv[3] = {"echo", "", NULL};
1044	char *samba_mode;
1045	char *samba_passwd;
1046
1047#ifdef LINUX26
1048	char lan_ifname[32], *lan_ifnames, *next;
1049	char path[64] = {0};
1050
1051	/* enabled gso on vlan interface */
1052	lan_ifnames = nvram_safe_get("lan_ifnames");
1053	foreach(lan_ifname, lan_ifnames, next) {
1054		if (!strncmp(lan_ifname, "vlan", 4)) {
1055			sprintf(path, ">>/proc/net/vlan/%s", lan_ifname);
1056			argv[1] = "-gro 2";
1057			_eval(argv, path, 0, NULL);
1058		}
1059	}
1060#endif
1061
1062	samba_mode = nvram_safe_get("samba_mode");
1063	samba_passwd = nvram_safe_get("samba_passwd");
1064
1065	/* Samba is disabled */
1066	if (strncmp(samba_mode, "1", 1) && strncmp(samba_mode, "2", 1))
1067		return 0;
1068
1069	/* Create smb.conf */
1070	argv[1] = "[global]";
1071	_eval(argv, ">/tmp/samba/lib/smb.conf", 0, NULL);
1072
1073	argv[1] = "workgroup = mygroup";
1074	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1075
1076	if (!strncmp(samba_mode, "1", 1))
1077		argv[1] = "security = user";
1078	else
1079		argv[1] = "security = share";
1080	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1081
1082#ifdef LINUX26
1083	argv[1] = "[media]";
1084#else
1085	argv[1] = "[mnt]";
1086#endif
1087	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1088
1089#ifdef LINUX26
1090	argv[1] = "path = /media";
1091#else
1092	argv[1] = "path = /mnt";
1093#endif
1094	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1095
1096	argv[1] = "writeable = yes";
1097	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1098
1099	argv[1] = "browseable = yes";
1100	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1101
1102	argv[1] = "guest ok = yes";
1103	_eval(argv, ">>/tmp/samba/lib/smb.conf", 0, NULL);
1104
1105	/* Start smbd */
1106	eval("smbd", "-D");
1107
1108	/* Set admin password */
1109	argv[1] = samba_passwd;
1110	_eval(argv, ">/tmp/spwd", 0, NULL);
1111	_eval(argv, ">>/tmp/spwd", 0, NULL);
1112	system("smbpasswd -a admin -s </tmp/spwd");
1113
1114	return 0;
1115}
1116
1117int
1118stop_samba()
1119{
1120	eval("killall", "smbd");
1121	eval("rm", "-r", "/tmp/samba/var/locks");
1122	eval("rm", "/tmp/samba/private/passdb.tdb");
1123
1124	return 0;
1125}
1126#endif
1127
1128#ifdef __CONFIG_DLNA_DMR__
1129int start_dlna_dmr()
1130{
1131	char *dlna_dmr_enable = nvram_safe_get("dlna_dmr_enable");
1132
1133	if (strcmp(dlna_dmr_enable, "1") == 0) {
1134		cprintf("Start bcmmrenderer.\n");
1135		eval("sh", "-c", "bcmmrenderer&");
1136	}
1137}
1138
1139int stop_dlna_dmr()
1140{
1141	cprintf("Stop bcmmrenderer.\n");
1142	eval("killall", "bcmmrenderer");
1143}
1144#endif
1145
1146
1147#ifdef __CONFIG_WL_ACI__
1148int start_wl_aci(void){
1149	int ret = 0;
1150
1151	/*
1152	 * If the ACI daemon is enabled, start the ACI daemon.  If not
1153	 *  simply return
1154	 */
1155	if (!nvram_match("aci_daemon", "up"))
1156		return 0;
1157
1158	ret = eval("wl_aci");
1159	return ret;
1160}
1161
1162int
1163stop_wl_aci(void)
1164{
1165	int ret;
1166
1167	ret = eval("killall", "wl_aci");
1168	return ret;
1169}
1170#endif /* __CONFIG_WL_ACI__ */
1171
1172#ifdef RWL_SOCKET
1173int
1174start_server_socket(void)
1175{
1176	char *srv_argv[] = {"/usr/sbin/wl_server_socket", NULL};
1177	pid_t pid;
1178
1179	_eval(srv_argv, NULL, 0, &pid);
1180
1181	return 0;
1182}
1183
1184int
1185stop_server_socket(void)
1186{
1187   	int ret = eval("killall","wl_server_socket");
1188
1189   	return ret;
1190}
1191#endif /* RWL_SOCKET */
1192
1193int
1194start_services(void)
1195{
1196/*
1197*/
1198#ifdef __CONFIG_IPV6__
1199	start_ipv6();
1200#endif /* __CONFIG_IPV6__ */
1201/*
1202*/
1203	start_httpd();
1204#ifdef __CONFIG_NAT__
1205	start_dns();
1206	start_dhcpd();
1207#ifdef	__CONFIG_UPNP__
1208	start_upnp();
1209#endif
1210#ifdef	__CONFIG_IGD__
1211	start_igd();
1212#endif
1213#endif	/* __CONFIG_NAT__ */
1214	start_eapd();
1215	start_nas();
1216#ifdef __CONFIG_WAPI_IAS__
1217	start_ias();
1218#endif /* __CONFIG_WAPI_IAS__ */
1219#ifdef __CONFIG_WAPI__
1220	start_wapid();
1221#endif /* __CONFIG_WAPI__ */
1222	start_wps();
1223#ifdef __CONFIG_UTELNETD__
1224	start_telnet();
1225#endif
1226#ifdef __CONFIG_IGMP_PROXY__
1227	start_igmp_proxy();
1228#endif /* __CONFIG_IGMP_PROXY__ */
1229#ifdef __CONFIG_WL_ACI__
1230	start_wl_aci();
1231#endif /* __CONFIG_WL_ACI__ */
1232#ifdef __CONFIG_LLD2D__
1233	start_lltd();
1234#endif /* __CONFIG_LLD2D__*/
1235#if defined(PHYMON)
1236	start_phymons();
1237#endif /* PHYMON */
1238#if defined(BCM_DCS) || defined(EXT_ACS)
1239	start_acsd();
1240#endif
1241#ifdef __CONFIG_SAMBA__
1242	start_samba();
1243#endif
1244
1245#ifdef __CONFIG_DLNA_DMR__
1246	start_dlna_dmr();
1247#endif
1248
1249#ifdef RWL_SOCKET
1250	start_server_socket();
1251#endif
1252
1253#ifdef PLC
1254	if (target_uses_gigled())
1255		start_gigled();
1256#endif
1257
1258	dprintf("done\n");
1259	return 0;
1260}
1261
1262int
1263stop_services(void)
1264{
1265	stop_wps();
1266#ifdef __CONFIG_WAPI__
1267	stop_wapid();
1268#endif /* __CONFIG_WAPI__ */
1269#ifdef __CONFIG_WAPI_IAS__
1270	stop_ias();
1271#endif /* __CONFIG_WAPI_IAS__ */
1272	stop_nas();
1273	stop_eapd();
1274#ifdef __CONFIG_NAT__
1275#ifdef	__CONFIG_IGD__
1276	stop_igd();
1277#endif
1278#ifdef	__CONFIG_UPNP__
1279	stop_upnp();
1280#endif
1281	stop_dhcpd();
1282	stop_dns();
1283#endif	/* __CONFIG_NAT__ */
1284	stop_httpd();
1285#ifdef __CONFIG_UTELNETD__
1286	stop_telnet();
1287#endif
1288#ifdef __CONFIG_IGMP_PROXY__
1289	stop_igmp_proxy();
1290#endif /* __CONFIG_IGMP_PROXY__ */
1291#ifdef __CONFIG_WL_ACI__
1292        stop_wl_aci();
1293#endif /* __CONFIG_WL_ACI__ */
1294#ifdef __CONFIG_LLD2D__
1295	stop_lltd();
1296#endif 	/* __CONFIG_LLD2D__*/
1297/*
1298*/
1299#ifdef __CONFIG_IPV6__
1300	stop_ipv6();
1301#endif /* __CONFIG_IPV6__ */
1302/*
1303*/
1304#if defined(PHYMON)
1305	stop_phymons();
1306#endif /* PHYMON */
1307#if defined(BCM_DCS) || defined(EXT_ACS)
1308	stop_acsd();
1309#endif
1310#ifdef __CONFIG_SAMBA__
1311	stop_samba();
1312#endif
1313#ifdef __CONFIG_DLNA_DMR__
1314	stop_dlna_dmr();
1315#endif
1316
1317#ifdef RWL_SOCKET
1318	stop_server_socket();
1319#endif
1320
1321#ifdef PLC
1322	if (target_uses_gigled())
1323		stop_gigled();
1324#endif
1325
1326	dprintf("done\n");
1327	return 0;
1328}
1329