1/* 2 * Miscellaneous services 3 * 4 * Copyright 2004, Broadcom Corporation 5 * All Rights Reserved. 6 * 7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 11 * 12 * $Id: services.c,v 1.4 2009/03/03 02:39:54 james26_jang Exp $ 13 */ 14 15#include <stdio.h> 16#include <stdlib.h> 17#include <string.h> 18#include <signal.h> 19#include <unistd.h> 20#include <errno.h> 21 22#include <bcmnvram.h> 23#include <netconf.h> 24#include <shutils.h> 25#include <rc.h> 26 27#ifndef ASUS_EXT 28int 29start_dhcpd(void) 30{ 31 FILE *fp; 32 char name[100]; 33 34 if (nvram_match("router_disable", "1") || nvram_invmatch("lan_proto", "dhcp")) 35 return 0; 36 37 dprintf("%s %s %s %s\n", 38 nvram_safe_get("lan_ifname"), 39 nvram_safe_get("dhcp_start"), 40 nvram_safe_get("dhcp_end"), 41 nvram_safe_get("lan_lease")); 42 43 /* Touch leases file */ 44 if (!(fp = fopen("/tmp/udhcpd.leases", "a"))) { 45 perror("/tmp/udhcpd.leases"); 46 return errno; 47 } 48 fclose(fp); 49 50 /* Write configuration file based on current information */ 51 if (!(fp = fopen("/tmp/udhcpd.conf", "w"))) { 52 perror("/tmp/udhcpd.conf"); 53 return errno; 54 } 55 fprintf(fp, "pidfile /var/run/udhcpd.pid\n"); 56 fprintf(fp, "start %s\n", nvram_safe_get("dhcp_start")); 57 fprintf(fp, "end %s\n", nvram_safe_get("dhcp_end")); 58 fprintf(fp, "interface %s\n", nvram_safe_get("lan_ifname")); 59 fprintf(fp, "remaining yes\n"); 60 fprintf(fp, "lease_file /tmp/udhcpd.leases\n"); 61 fprintf(fp, "option subnet %s\n", nvram_safe_get("lan_netmask")); 62 fprintf(fp, "option router %s\n", nvram_safe_get("lan_ipaddr")); 63 fprintf(fp, "option dns %s\n", nvram_safe_get("lan_ipaddr")); 64 fprintf(fp, "option lease %s\n", nvram_safe_get("lan_lease")); 65 snprintf(name, sizeof(name), "%s_wins", nvram_safe_get("dhcp_wins")); 66 if (nvram_invmatch(name, "")) 67 fprintf(fp, "option wins %s\n", nvram_get(name)); 68 snprintf(name, sizeof(name), "%s_domain", nvram_safe_get("dhcp_domain")); 69 if (nvram_invmatch(name, "")) 70 fprintf(fp, "option domain %s\n", nvram_get(name)); 71 fclose(fp); 72 73 eval("udhcpd", "-i", "br0", "/tmp/udhcpd.conf"); 74 75 dprintf("done\n"); 76 return 0; 77} 78 79int 80stop_dhcpd(void) 81{ 82 char sigusr1[] = "-XX"; 83 int ret; 84 85/* 86* Process udhcpd handles two signals - SIGTERM and SIGUSR1 87* 88* - SIGUSR1 saves all leases in /tmp/udhcpd.leases 89* - SIGTERM causes the process to be killed 90* 91* The SIGUSR1+SIGTERM behavior is what we like so that all current client 92* leases will be honorred when the dhcpd restarts and all clients can extend 93* their leases and continue their current IP addresses. Otherwise clients 94* would get NAK'd when they try to extend/rebind their leases and they 95* would have to release current IP and to request a new one which causes 96* a no-IP gap in between. 97*/ 98 sprintf(sigusr1, "-%d", SIGUSR1); 99 eval("killall", sigusr1, "udhcpd"); 100 ret = eval("killall", "udhcpd"); 101 102 dprintf("done\n"); 103 return ret; 104} 105 106int 107start_dns(void) 108{ 109 int ret; 110 FILE *fp; 111 112 if (nvram_match("router_disable", "1")) 113 return 0; 114 115 /* Create resolv.conf with empty nameserver list */ 116 if (!(fp = fopen("/tmp/resolv.conf", "w"))) { 117 perror("/tmp/resolv.conf"); 118 return errno; 119 } 120 fclose(fp); 121 122 /* launch dns relay */ 123 ret = eval("dnsmasq", "-h", 124 "-i", nvram_safe_get("lan_ifname"), 125 "-r", "/tmp/resolv.conf"); 126 127 dprintf("done\n"); 128 return ret; 129} 130 131int 132stop_dns(void) 133{ 134 int ret = eval("killall", "dnsmasq"); 135 136 /* Remove resolv.conf */ 137 unlink("/tmp/resolv.conf"); 138 139 dprintf("done\n"); 140 return ret; 141} 142#endif 143 144int 145start_httpd(void) 146{ 147 int ret; 148 149 chdir("/www"); 150#ifdef ASUS_EXT 151 if (nvram_invmatch("router_disable", "1")) 152 ret = eval("httpd", nvram_safe_get("wan0_ifname")); 153 else 154#endif 155 ret = eval("httpd"); 156 157 chdir("/"); 158 159 dprintf("done\n"); 160 return ret; 161} 162 163int 164stop_httpd(void) 165{ 166 int ret = eval("killall", "httpd"); 167 168 dprintf("done\n"); 169 return ret; 170} 171 172int 173start_upnp(void) 174{ 175 char *wan_ifname; 176 int ret; 177 char var[100], prefix[] = "wanXXXXXXXXXX_"; 178 179 if (!nvram_invmatch("upnp_enable", "0") || nvram_match("router_disable", "1")) 180 return 0; 181 182 ret = eval("killall", "-SIGUSR1", "upnp"); 183 if (ret != 0) { 184 snprintf(prefix, sizeof(prefix), "wan%d_", wan_primary_ifunit()); 185 wan_ifname = nvram_match(strcat_r(prefix, "proto", var), "pppoe") ? 186 nvram_safe_get(strcat_r(prefix, "pppoe_ifname", var)) : 187 nvram_safe_get(strcat_r(prefix, "ifname", var)); 188 ret = eval("upnp", "-D", 189 "-L", nvram_safe_get("lan_ifname"), 190 "-W", wan_ifname); 191 192 } 193 dprintf("done\n"); 194 return ret; 195} 196 197int 198stop_upnp(void) 199{ 200 int ret = 0; 201 202 if(nvram_invmatch("upnp_enable", "0")) 203 ret = eval("killall", "upnp"); 204 205 dprintf("done\n"); 206 return ret; 207} 208 209int 210start_nas(char *type) 211{ 212 char cfgfile[64]; 213 char pidfile[64]; 214 if (!type || !*type) 215 type = "lan"; 216 snprintf(cfgfile, sizeof(cfgfile), "/tmp/nas.%s.conf", type); 217 snprintf(pidfile, sizeof(pidfile), "/tmp/nas.%s.pid", type); 218 { 219 char *argv[] = {"nas", cfgfile, pidfile, type, NULL}; 220 pid_t pid; 221 222 _eval(argv, NULL, 0, &pid); 223 dprintf("done\n"); 224 } 225 return 0; 226} 227 228int 229stop_nas(void) 230{ 231 int ret = eval("killall", "nas"); 232 233 dprintf("done\n"); 234 return ret; 235} 236 237int 238start_ntpc(void) 239{ 240#ifdef ASUS_EXT 241 char *ntp_argv[] = {"ntp", NULL}; 242 pid_t pid; 243 244 _eval(ntp_argv, NULL, 0, &pid); 245#else 246 char *servers = nvram_safe_get("ntp_server"); 247 char *ntp_argv[] = {"ntpclient", "-h", servers, "-i", "3", "-l", "-s", NULL}; 248 249 if (strlen(servers)) { 250 _eval(ntp_argv, NULL, 0, NULL); 251 } 252 253 dprintf("done\n"); 254#endif 255 return 0; 256} 257 258int 259stop_ntpc(void) 260{ 261#ifdef ASUS_EXT 262 int ret = eval("killall", "ntp"); 263#else 264 int ret = eval("killall", "ntpclient"); 265#endif 266 267 dprintf("done\n"); 268 return ret; 269} 270 271/* +++ Cherry Cho added in 2006/12/14. +++ */ 272int start_lltd(void) 273{ 274 chdir("/usr/sbin"); 275 eval("lld2d", "br0"); 276 chdir("/"); 277 278 return 0; 279} 280 281int stop_lltd(void)/* Cherry Cho added in 2006/12/14. */ 282{ 283 int ret; 284 285 ret = eval("killall", "lld2d"); 286 287 return ret; 288} 289 290#ifdef WSC 291int 292start_wsc(void) 293{ 294 295 /* Set values of WSC variables */ 296 297 if(nvram_get("secret_code"))/* Cherry Cho added in 2007/4/13. */ 298 nvram_set("wsc_device_pin", nvram_safe_get("secret_code")); 299 300 if((!nvram_match("wsc_cli","1")) && nvram_match("wsc_mode","enabled")) 301 { 302 if (nvram_match("wsc_restart", "no")) { 303 nvram_set("wsc_restart", "normal"); 304 } 305 else 306 { 307 char *wsc_argv[] = {"/bin/wsccmd", NULL}; 308 pid_t pid; 309 310 dprintf("Starting wsc\n"); 311 nvram_set("wsc_restart", "yes"); 312 _eval(wsc_argv, NULL, 0, &pid); 313 sleep(5); 314 } 315 } 316 return 0; 317} 318 319int 320stop_wsc(void) 321{ 322 int ret; 323 324 //if((!nvram_match("wsc_cli","1")) && nvram_match("wsc_mode","enabled")) 325 if(!nvram_match("wsc_cli","1")) 326 { 327 if (nvram_match("wsc_restart", "no")) { 328 return 0; 329 } 330 else 331 { 332 nvram_set("wsc_restart", "yes"); 333 ret = eval("killall","wsccmd"); 334 } 335 } 336 return ret; 337} 338#endif 339/* --- Cherry Cho added in 2006/12/14. --- */ 340 341int 342start_services(void) 343{ 344 start_httpd(); 345 start_dns(); 346 start_dhcpd(); 347 348#ifdef ASUS_EXT 349 start_logger(); 350#endif 351 352 start_upnp(); 353 354 start_nas("lan"); 355 356#ifdef ASUS_EXT 357 start_usb(); 358#endif 359 360#ifdef GUEST_ACCOUNT 361 if (nvram_match("wl_guest_enable", "1")) 362 { 363 sleep(5); 364 start_dhcpd_guest(); 365 start_guest_nas(); 366 } 367#endif 368 369 start_lltd(); /* Cherry Cho added in 2006/12/14. */ 370 371// 2007.11 James { 372#ifdef WEB_REDIRECT 373 if(!nvram_match("wanduck_down", "1") 374 && nvram_match("wan_nat_x", "1")){ 375 printf("--- START: Wait to start wanduck ---\n"); 376 redirect_setting(); 377 start_wanduck(); 378 sleep(1); 379 } 380#endif 381// 2007.11 James } 382#ifdef DLM 383// 2007.10 James { 384 if(!strcmp(nvram_safe_get("restart_usb_apps"), "1")){ 385 nvram_unset("restart_usb_apps"); 386 start_usb_apps(); 387 } 388// 2007.10 James } 389#endif 390 dprintf("done\n"); 391 392 return 0; 393} 394 395int 396stop_services(void) 397{ 398// 2007.10 James { 399 if(!strcmp(nvram_safe_get("samba_running"), "1") || 400 !strcmp(nvram_safe_get("ftp_running"), "1") || 401 !strcmp(nvram_safe_get("apps_running"), "1") 402 ){ 403printf("\n*** ready to restart_usb_apps ***\n"); 404 nvram_set("restart_usb_apps", "1"); 405 } 406// 2007.10 James } 407 408#ifdef ASUS_EXT 409 stop_usb(); 410#endif 411 stop_nas(); 412 stop_upnp(); 413#ifdef ASUS_EXT 414 stop_logger(); 415#endif 416 417#ifdef GUEST_ACCOUNT 418 stop_dhcpd_guest(); 419#endif 420 stop_dhcpd(); 421 stop_dns(); 422 stop_httpd(); 423 424 stop_lltd();/* Cherry Cho added in 2006/12/14. */ 425 dprintf("done\n"); 426 return 0; 427} 428 429#ifdef GUEST_ACCOUNT 430/* Start NAS for the guest interfaces */ 431int 432start_guest_nas(void) 433{ 434 char *unbridged_interfaces; 435 char *next; 436 char name[IFNAMSIZ],lan[IFNAMSIZ]; 437 int index; 438 439 unbridged_interfaces = nvram_get("unbridged_ifnames"); 440 441 if (unbridged_interfaces) 442 foreach(name,unbridged_interfaces,next){ 443 index = get_ipconfig_index(name); 444 if (index < 0) 445 continue; 446 snprintf(lan,sizeof(lan),"lan%d",index); 447 start_nas(lan); 448 } 449 450 return 0; 451} 452#endif 453 454// 2007.10 James { 455#ifdef WEB_REDIRECT 456int start_wanduck(void){ 457// kill_pidfile_s("/var/run/wanduckmain.pid", SIGUSR1); 458 char *argv[] = {"/usr/sbin/wanduck", NULL}; 459 int ret = 0; 460 pid_t pid; 461 FILE *fp = fopen("/var/run/wanduck.pid", "r"); 462 if(fp != NULL){ 463 fclose(fp); 464 return 0; 465 } 466 467 ret = _eval(argv, NULL, 0, &pid); 468 469 return ret; 470} 471 472int stop_wanduck(void){ 473// kill_pidfile_s("/var/run/wanduckmain.pid", SIGUSR2); 474 kill_pidfile_s("/var/run/wanduck.pid", SIGTERM); 475 476 return 0; 477} 478#endif 479// 2007.10 James } 480