Project

General

Profile

Download (34.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services.inc
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31

    
32
/* include all configuration functions */
33
require_once("functions.inc");
34

    
35
function load_balancer_use_sticky() {
36
	global $config, $g;
37
	if (isset ($config['system']['lb_use_sticky']))
38
		touch("/var/etc/use_pf_pool__stickyaddr");
39
	else
40
		unlink_if_exists("/var/etc/use_pf_pool__stickyaddr");
41
}
42

    
43
function services_dhcpd_configure() {
44
	global $config, $g;
45
	if(isset($config['system']['developerspew'])) {
46
		$mt = microtime();
47
		echo "services_dhcpd_configure($if) being called $mt\n";
48
	}
49

    
50
	/* if OLSRD is enabled, allow WAN to house DHCP. */
51
	if($config['installedpackages']['olsrd'])
52
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
53
				if($olsrd['enable'])
54
					$is_olsr_enabled = true;
55

    
56
	/* configure DHCPD chroot */
57
	$fd = fopen("/tmp/dhcpd.sh","w");
58
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
59
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
60
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
61
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
62
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
63
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
64
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
65
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
66
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
67
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
68
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
69
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
70
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
71
	if(!trim($status))
72
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
73
	fclose($fd);
74
	mwexec("/bin/sh /tmp/dhcpd.sh");
75

    
76
	/* kill any running dhcpd */
77
	if(is_process_running("dhcpd"))
78
		mwexec("killall dhcpd");
79

    
80
	$syscfg = $config['system'];
81
	$dhcpdcfg = $config['dhcpd'];
82

    
83
	/* DHCP enabled on any interfaces? */
84
	$dhcpdenable = false;
85
	if(is_array($dhcpdcfg))
86
		foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
87
			if (isset($dhcpifconf['enable']) &&
88
				(($dhcpif == "lan") ||
89
				(isset($config['interfaces'][$dhcpif]['enable']) &&
90
				$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
91
				$dhcpdenable = true;
92
			if (isset($dhcpifconf['enable']) &&
93
				(($dhcpif == "wan") || (isset($config['interfaces'][$dhcpif]['enable']) &&
94
				$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
95
				$dhcpdenable = true;
96
		}
97

    
98
	if (!$dhcpdenable)
99
		return 0;
100

    
101
	if ($g['booting'])
102
		echo "Starting DHCP service...";
103
	else
104
		sleep(1);
105

    
106
	/* write dhcpd.conf */
107
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
108
	if (!$fd) {
109
		printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
110
		return 1;
111
	}
112

    
113

    
114

    
115
	$dhcpdconf = <<<EOD
116
option domain-name "{$syscfg['domain']}";
117
default-lease-time 7200;
118
max-lease-time 86400;
119
authoritative;
120
log-facility local7;
121
ddns-update-style none;
122
one-lease-per-client true;
123
deny duplicates;
124

    
125
EOD;
126

    
127
	$dhcpdifs = array();
128

    
129
	/*    loop through and deterimine if we need to setup
130
	 *    failover peer "bleh" entries
131
	 */
132
	$dhcpnum = 0;
133
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
134
		if($dhcpifconf['failover_peerip'] <> "") {
135
			/*
136
			 *    yep, failover peer is defined.
137
			 *    does it match up to a defined vip?
138
			 */
139
			$skew = 110;
140
			$a_vip = &$config['virtualip']['vip'];
141
			if(is_array($a_vip)) {
142
				foreach ($a_vip as $vipent) {
143
					$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
144
					$intip = find_interface_ip($int);
145
					$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
146
					if($int == $real_dhcpif) {
147
						/* this is the interface! */
148
						if($vipent['advskew'] < "20")
149
							$skew = 0;
150
					}
151
				}
152
			} else {
153
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
154
			}
155
			if($skew > 10) {
156
				$type = "secondary";
157
				$dhcpdconf_pri  = "mclt 600;\n";
158
				$my_port = "520";
159
				$peer_port = "519";
160
			} else {
161
				$my_port = "519";
162
				$peer_port = "520";
163
				$type = "primary";
164
				$dhcpdconf_pri  = "split 128;\n";
165
				$dhcpdconf_pri .= "  mclt 600;\n";
166
			}
167
			$dhcpdconf .= <<<EOPP
168
failover peer "dhcp{$dhcpnum}" {
169
  {$type};
170
  address {$intip};
171
  port {$my_port};
172
  peer address {$dhcpifconf['failover_peerip']};
173
  peer port {$peer_port};
174
  max-response-delay 10;
175
  max-unacked-updates 10;
176
  {$dhcpdconf_pri}
177
  load balance max seconds 3;
178
}
179

    
180
EOPP;
181
		$dhcpnum++;
182
		}
183
	}
184

    
185
	$dhcpnum = 0;
186

    
187
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
188

    
189
		$ifcfg = $config['interfaces'][$dhcpif];
190

    
191
		if (!isset($dhcpifconf['enable']) ||
192
			($ifcfg['ipaddr'] == "dhcp") ||
193
			(($dhcpif != "lan") &&
194
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
195
			continue;
196

    
197
		if($dhcpif == "lan" && $ifcfg['bridge'])
198
			log_error("NOTE: DHCP Server on LAN is enabled.");
199

    
200
		$subnet = gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);
201
		$subnetmask = gen_subnet_mask($ifcfg['subnet']);
202

    
203
		if($is_olsr_enabled == true)
204
			if($dhcpifconf['netmask'])
205
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
206

    
207
		$dnscfg = "";
208

    
209
		if ($dhcpifconf['domain']) {
210
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
211
		}
212
		if (isset($dhcpifconf['ddnsupdate'])) {
213
			if($dhcpifconf['ddnsdomain'] <> "") {
214
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
215
			}
216
			$dnscfg .= "	ddns-update-style interim;\n";
217
		}
218

    
219

    
220
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
221
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
222
		} else if (isset($config['dnsmasq']['enable'])) {
223
			$dnscfg .= "	option domain-name-servers " . $ifcfg['ipaddr'] . ";";
224
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
225
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
226
		}
227

    
228
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
229
		$dhcpdconf .= "	pool {\n";
230

    
231
		/* is failover dns setup? */
232
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
233
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
234
			if($dhcpifconf['dnsserver'][1] <> "")
235
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
236
			$dhcpdconf .= ";\n";
237
		}
238

    
239
		if($dhcpifconf['failover_peerip'] <> "")
240
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
241

    
242
		if (isset($dhcpifconf['denyunknown']))
243
		   $dhcpdconf .= "		deny unknown clients;\n";
244

    
245
		if ($dhcpifconf['gateway'])
246
			$routers = $dhcpifconf['gateway'];
247
		else
248
			$routers = $ifcfg['ipaddr'];
249

    
250
		if($dhcpifconf['failover_peerip'] <> "") {
251
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
252
			$dhcpnum++;
253
		}
254

    
255
		$dhcpdconf .= <<<EOD
256
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
257
	}
258
	option routers {$routers};
259
$dnscfg
260

    
261
EOD;
262

    
263
		if ($dhcpifconf['defaultleasetime'])
264
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
265
		if ($dhcpifconf['maxleasetime'])
266
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
267

    
268
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
269
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
270
			$dhcpdconf .= "	option netbios-node-type 8;\n";
271
		}
272

    
273
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
274
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
275

    
276
		if(isset($dhcpifconf['netboot'])) {
277
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
278
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
279
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
280
			}
281
		}
282
		$dhcpdconf .= <<<EOD
283
}
284

    
285
EOD;
286

    
287
		/* add static mappings */
288
		if (is_array($dhcpifconf['staticmap'])) {
289

    
290
			$i = 0;
291
			foreach ($dhcpifconf['staticmap'] as $sm) {
292
				$dhcpdconf .= <<<EOD
293
host s_{$dhcpif}_{$i} {
294
	hardware ethernet {$sm['mac']};
295

    
296
EOD;
297
				if ($sm['ipaddr'])
298
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
299

    
300
				$dhcpdconf .= "}\n";
301
				$i++;
302
			}
303
		}
304

    
305
		$dhcpdifs[] = $ifcfg['if'];
306
	}
307

    
308
	fwrite($fd, $dhcpdconf);
309
	fclose($fd);
310

    
311
	/* create an empty leases database */
312
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
313

    
314
	/* fire up dhcpd in a chroot */
315
	mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf {$g['dhcpd_chroot_path']}/etc/dhcpd.conf " .
316
		join(" ", $dhcpdifs));
317

    
318
	if ($g['booting']) {
319
		print "done.\n";
320
	}
321

    
322
	return 0;
323
}
324

    
325
function interfaces_staticarp_configure($if) {
326
	global $config, $g;
327
	if(isset($config['system']['developerspew'])) {
328
		$mt = microtime();
329
		echo "interfaces_staticarp_configure($if) being called $mt\n";
330
	}
331

    
332
        $ifcfg = $config['interfaces'][$if];
333

    
334
        /* Enable staticarp, if enabled */
335
        if(isset($config['dhcpd'][$if]['staticarp'])) {
336
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
337
                mwexec("/usr/sbin/arp -ad > /dev/null 2>&1 ");
338
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
339

    
340
                        foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
341
                                mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
342
								log_error("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
343
                        }
344

    
345
                }
346
        } else {
347
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
348
                mwexec("/usr/sbin/arp -da > /dev/null 2>&1 ");
349
        }
350

    
351
        return 0;
352
}
353

    
354
function services_dhcrelay_configure() {
355
	global $config, $g;
356
	if(isset($config['system']['developerspew'])) {
357
		$mt = microtime();
358
		echo "services_dhcrelay_configure() being called $mt\n";
359
	}
360

    
361
	/* kill any running dhcrelay */
362
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
363

    
364
	$dhcrelaycfg = $config['dhcrelay'];
365

    
366
	/* DHCPRelay enabled on any interfaces? */
367
	$dhcrelayenable = false;
368
	if(is_array($dhcrelaycfg)) {
369
		foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
370
			if (isset($dhcrelayifconf['enable']) &&
371
				(($dhcrelayif == "lan") ||
372
				(isset($config['interfaces'][$dhcrelayif]['enable']) &&
373
				$config['interfaces'][$dhcrelayif]['if'] && (!$config['interfaces'][$dhcrelayif]['bridge']))))
374
				$dhcrelayenable = true;
375
		}
376
	}
377

    
378
	if (!$dhcrelayenable)
379
		return 0;
380

    
381
	if ($g['booting'])
382
		echo "Starting DHCP relay service...";
383
	else
384
		sleep(1);
385

    
386
	$dhcrelayifs = array();
387
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
388

    
389
		$ifcfg = $config['interfaces'][$dhcrelayif];
390

    
391
		if (!isset($dhcrelayifconf['enable']) ||
392
			(($dhcrelayif != "lan") &&
393
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
394
			continue;
395

    
396
		$dhcrelayifs[] = $ifcfg['if'];
397
	}
398

    
399
	/* In order for the relay to work, it needs to be active on the
400
	   interface in which the destination server sits */
401
	foreach ($config['interfaces'] as $ifname) {
402
		$subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
403
		if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
404
			$destif = $ifname['if'];
405
	}
406

    
407
	if (!isset($destif))
408
		$destif = $config['interfaces']['wan']['if'];
409

    
410
	$dhcrelayifs[] = $destif;
411
	$dhcrelayifs = array_unique($dhcrelayifs);
412

    
413
	/* fire up dhcrelay */
414
	$cmd = "/usr/local/sbin/dhcrelay -i " .  join(" -i ", $dhcrelayifs);
415

    
416
	if (isset($dhcrelaycfg['agentoption']))
417
		$cmd .=  " -a -m replace";
418

    
419
	$cmd .= " {$dhcrelaycfg['server']}";
420
	mwexec($cmd);
421

    
422
	if (!$g['booting']) {
423
		/* set the reload filter dity flag */
424
		touch("{$g['tmp_path']}/filter_dirty");
425
	}
426

    
427
	return 0;
428
}
429

    
430
function services_dyndns_reset() {
431
	global $config, $g;
432
	if(isset($config['system']['developerspew'])) {
433
		$mt = microtime();
434
		echo "services_dyndns_reset() being called $mt\n";
435
	}
436

    
437
	if (file_exists("{$g['vardb_path']}/ez-ipupdate.cache")) {
438
		conf_mount_rw();
439
		unlink("{$g['vardb_path']}/ez-ipupdate.cache");
440
		conf_mount_ro();
441
	}
442

    
443
	if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
444
		conf_mount_rw();
445
		unlink("{$g['conf_path']}/ez-ipupdate.cache");
446
		conf_mount_ro();
447
	}
448
	
449
	if (file_exists("{$g['conf_path']}/dyndns.cache")) {
450
		conf_mount_rw();
451
		unlink("{$g['conf_path']}/dyndns.cache");
452
		conf_mount_ro();
453
	}
454

    
455
	return 0;
456
}
457

    
458
function services_dyndns_configure() {
459
	global $config, $g;
460
	if(isset($config['system']['developerspew'])) {
461
		$mt = microtime();
462
		echo "services_dyndns_configure() being called $mt\n";
463
	}
464

    
465
	$dyndnscfg = $config['dyndns'];
466
	$wancfg = $config['interfaces']['wan'];
467

    
468
	if (isset($dyndnscfg['enable'])) {
469

    
470
		if ($g['booting']) {
471
			echo "Starting DynDNS client...";
472
			if(isset($config['system']['use_old_dyndns'])) {
473
				echo " [Using ez-ipupdate] ";
474
				services_dyndns_configure_old();
475
				return;
476
			}
477
		} else {
478
			sleep(1);
479
			if(isset($config['system']['use_old_dyndns'])) {
480
				services_dyndns_configure_old();
481
				return;
482
			}
483
		}
484

    
485
		/* load up the dyndns.class */
486
		require_once("dyndns.class");
487

    
488
		log_error("DynDns: Running updatedns()");
489

    
490
		/* determine WAN interface name */
491
		$wanif = get_real_wan_interface();
492
		/* get ip */
493
		$ip = find_interface_ip($wanif);
494

    
495
		$dns = new updatedns($dnsService = $config['dyndns']['type'],
496
							 $dnsHost = $config['dyndns']['host'],
497
							 $dnsUser = $config['dyndns']['username'],
498
							 $dnsPass = $config['dyndns']['password'],
499
							 $dnsWilcard = $config['dyndns']['wildcard'],
500
							 $dnsMX = $config['dyndns']['mx']);
501

    
502
		if ($g['booting'])
503
			echo "done.\n";
504
	}
505

    
506
	return 0;
507
}
508

    
509
function services_dyndns_configure_old() {
510
	global $config, $g;
511
	if(isset($config['system']['developerspew'])) {
512
		$mt = microtime();
513
		echo "services_dyndns_configure_old() being called $mt\n";
514
	}
515

    
516
        /* kill any running ez-ipupdate */
517
        /* ez-ipupdate needs SIGQUIT instead of SIGTERM */
518
        sigkillbypid("{$g['varrun_path']}/ez-ipupdate.pid", "QUIT");
519

    
520
        $dyndnscfg = $config['dyndns'];
521
        $wancfg = $config['interfaces']['wan'];
522

    
523
        if (isset($dyndnscfg['enable'])) {
524

    
525
                if ($g['booting'])
526
                        echo "Starting DynDNS client...";
527
                else
528
                        sleep(1);
529

    
530
                /* determine WAN interface name */
531
                $wanif = get_real_wan_interface();
532

    
533
                /* write ez-ipupdate.conf */
534
                $fd = fopen("{$g['varetc_path']}/ez-ipupdate.conf", "w");
535
                if (!$fd) {
536
                        printf("Error: cannot open ez-ipupdate.conf in services_dyndns_configure().\n");
537
                        return 1;
538
                }
539

    
540
                $ezipupdateconf = <<<EOD
541
service-type={$dyndnscfg['type']}
542
user={$dyndnscfg['username']}:{$dyndnscfg['password']}
543
host={$dyndnscfg['host']}
544
interface={$wanif}
545
max-interval=2073600
546
pid-file={$g['varrun_path']}/ez-ipupdate.pid
547
cache-file={$g['vardb_path']}/ez-ipupdate.cache
548
execute=/etc/rc.dyndns.storecache
549
daemon
550

    
551
EOD;
552

    
553
                /* enable server[:port]? */
554
                if ($dyndnscfg['server']) {
555
                        if ($dyndnscfg['port'])
556
                                $ezipupdateconf .= "server={$dyndnscfg['server']}:{$dyndnscfg['port']}\n";
557
                        else
558
                                $ezipupdateconf .= "server={$dyndnscfg['server']}\n";
559
                }
560

    
561
                /* enable MX? */
562
                if ($dyndnscfg['mx']) {
563
                        $ezipupdateconf .= "mx={$dyndnscfg['mx']}\n";
564
                }
565

    
566
                /* enable wildcards? */
567
                if (isset($dyndnscfg['wildcard'])) {
568
                        $ezipupdateconf .= "wildcard\n";
569
                }
570

    
571
                fwrite($fd, $ezipupdateconf);
572
                fclose($fd);
573

    
574
                /* if we're booting, copy the cache file from /conf */
575
                if ($g['booting']) {
576
                        if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
577
                                copy("{$g['conf_path']}/ez-ipupdate.cache", "{$g['vardb_path']}/ez-ipupdate.cache");
578
                       }
579
                }
580

    
581
                /* run ez-ipupdate */
582
                mwexec("/usr/local/bin/ez-ipupdate -c {$g['varetc_path']}/ez-ipupdate.conf");
583

    
584
                if ($g['booting'])
585
                        echo "done\n";
586
        }
587

    
588
        return 0;
589
}
590

    
591
function services_dnsmasq_configure() {
592
	global $config, $g;
593
	$return = 0;
594
	
595
	if(isset($config['system']['developerspew'])) {
596
		$mt = microtime();
597
		echo "services_dnsmasq_configure() being called $mt\n";
598
	}
599

    
600
	/* kill any running dnsmasq */
601
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
602

    
603
	if (isset($config['dnsmasq']['enable'])) {
604

    
605
		if ($g['booting'])
606
			echo "Starting DNS forwarder...";
607
		else
608
			sleep(1);
609

    
610
		/* generate hosts file */
611
		if(system_hosts_generate()!=0)
612
			$return = 1;
613

    
614
		$args = "";
615

    
616
		if (isset($config['dnsmasq']['regdhcp'])) {
617

    
618
			$args .= " -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases" .
619
				" -s {$config['system']['domain']}";
620
		}
621

    
622
                if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
623
                        foreach($config['dnsmasq']['domainoverrides'] as $override) {
624
                                $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
625
                        }
626
                }
627

    
628
		/* suppose that dnsmasq handles our domain and don't send
629
		requests for our local domain to upstream servers */
630
		//if (!empty($config['system']['domain'])) {
631
		//	$args .= sprintf(' --local=/%s/', $config['system']['domain']);
632
		//}
633

    
634
		/* run dnsmasq */
635
		mwexec("/usr/local/sbin/dnsmasq {$args}");
636

    
637
		if ($g['booting'])
638
			echo "done.\n";
639
	}
640

    
641
	if (!$g['booting']) {
642
		if(services_dhcpd_configure()!=0)
643
			$return = 1;
644
	}
645

    
646
	return $return;
647
}
648

    
649
function services_snmpd_configure() {
650
	global $config, $g;
651
	if(isset($config['system']['developerspew'])) {
652
		$mt = microtime();
653
		echo "services_snmpd_configure() being called $mt\n";
654
	}
655

    
656
	/* kill any running snmpd */
657
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
658
	if(is_process_running("bsnmpd")) 
659
		exec("/usr/bin/killall bsnmpd");
660

    
661
	if (isset($config['snmpd']['enable'])) {
662

    
663
		if ($g['booting'])
664
			echo "Starting SNMP daemon... ";
665

    
666
		/* generate snmpd.conf */
667
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
668
		if (!$fd) {
669
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
670
			return 1;
671
		}
672

    
673

    
674
		$snmpdconf = <<<EOD
675
location := "{$config['snmpd']['syslocation']}"
676
contact := "{$config['snmpd']['syscontact']}"
677
read := "{$config['snmpd']['rocommunity']}"
678

    
679
EOD;
680

    
681
/* No docs on what write strings do there for disable for now.
682
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
683
		    $snmpdconf .= <<<EOD
684
# write string
685
write := "{$config['snmpd']['rwcommunity']}"
686

    
687
EOD;
688
		}
689
*/
690

    
691

    
692
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
693
		    $snmpdconf .= <<<EOD
694
# SNMP Trap support.
695
traphost := {$config['snmpd']['trapserver']}
696
trapport := {$config['snmpd']['trapserverport']}
697
trap := "{$config['snmpd']['trapstring']}"
698

    
699

    
700
EOD;
701
		}
702

    
703

    
704
		$snmpdconf .= <<<EOD
705
system := 1     # pfSense
706
%snmpd
707
begemotSnmpdDebugDumpPdus       = 2
708
begemotSnmpdDebugSyslogPri      = 7
709
begemotSnmpdCommunityString.0.1 = $(read)
710

    
711
EOD;
712

    
713
/* No docs on what write strings do there for disable for now.
714
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
715
		    $snmpdconf .= <<<EOD
716
begemotSnmpdCommunityString.0.2 = $(write)
717

    
718
EOD;
719
		}
720
*/
721

    
722

    
723
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
724
		    $snmpdconf .= <<<EOD
725
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
726
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
727
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
728

    
729
EOD;
730
		}
731

    
732

    
733
		$snmpdconf .= <<<EOD
734
begemotSnmpdCommunityDisable    = 1
735

    
736
EOD;
737

    
738
		if(isset($config['snmpd']['bindlan'])) {
739
			$bind_to_ip = $config['interfaces']['lan']['ipaddr'];
740
		} else {
741
			$bind_to_ip = "0.0.0.0";
742
		}
743

    
744
		if(is_port( $config['snmpd']['pollport'] )) {
745
		    $snmpdconf .= <<<EOD
746
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
747

    
748
EOD;
749

    
750
		}
751

    
752
		$snmpdconf .= <<<EOD
753
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
754
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
755

    
756
# These are bsnmp macros not php vars.
757
sysContact      = $(contact)
758
sysLocation     = $(location)
759
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
760

    
761
snmpEnableAuthenTraps = 2
762

    
763
EOD;
764

    
765
		if (is_array( $config['snmpd']['modules'] )) {
766
		    if(isset($config['snmpd']['modules']['mibii'])) {
767
			$snmpdconf .= <<<EOD
768
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
769

    
770
EOD;
771
		    }
772

    
773
		    if(isset($config['snmpd']['modules']['netgraph'])) {
774
			$snmpdconf .= <<<EOD
775
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
776
%netgraph
777
begemotNgControlNodeName = "snmpd"
778

    
779
EOD;
780
		    }
781

    
782
		    if(isset($config['snmpd']['modules']['pf'])) {
783
			$snmpdconf .= <<<EOD
784
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
785

    
786
EOD;
787
		    }
788

    
789
		    if(isset($config['snmpd']['modules']['hostres'])) {
790
			$snmpdconf .= <<<EOD
791
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
792

    
793
EOD;
794
		    }
795
		    if(isset($config['snmpd']['modules']['bridge'])) {
796
			$snmpdconf .= <<<EOD
797
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
798
# config must end with blank line
799

    
800

    
801
EOD;
802
		    }
803
		}
804

    
805
		fwrite($fd, $snmpdconf);
806
		fclose($fd);
807

    
808
		if (isset($config['snmpd']['bindlan'])) {
809
			$bindlan = "";
810
		}
811

    
812
		/* run bsnmpd */
813
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
814
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
815

    
816
		if ($g['booting'])
817
			echo "done.\n";
818
	}
819

    
820
	return 0;
821
}
822

    
823
function services_proxyarp_configure() {
824
	global $config, $g;
825
	if(isset($config['system']['developerspew'])) {
826
		$mt = microtime();
827
		echo "services_proxyarp_configure() being called $mt\n";
828
	}
829

    
830
	/* kill any running choparp */
831
	killbyname("choparp");
832

    
833
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
834
		$paa = array();
835

    
836
		/* group by interface */
837
		foreach ($config['virtualip']['vip'] as $vipent) {
838
			if ($vipent['mode'] === "proxyarp") {
839
				if ($vipent['interface'])
840
					$if = $vipent['interface'];
841
				else
842
					$if = "wan";
843

    
844
				if (!is_array($paa[$if]))
845
					$paa[$if] = array();
846

    
847
				$paa[$if][] = $vipent;
848
			}
849
		}
850

    
851
		if (count($paa))
852
		foreach ($paa as $paif => $paents) {
853
			if ($paif == "wan" && !(is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
854
                                       ($config['interfaces']['wan']['ipaddr'] == "dhcp") ||
855
                                       ($config['interfaces']['wan']['ipaddr'] == "bigpond")))
856
                               continue;
857

    
858
			$args = $config['interfaces'][$paif]['if'] . " auto";
859

    
860
			foreach ($paents as $paent) {
861

    
862
				if (isset($paent['subnet']))
863
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
864
				else if (isset($paent['range']))
865
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
866
						$paent['range']['to']);
867
			}
868

    
869
			mwexec_bg("/usr/local/sbin/choparp " . $args);
870
		}
871
	}
872
}
873

    
874
function services_dnsupdate_process() {
875
	global $config, $g;
876
	if(isset($config['system']['developerspew'])) {
877
		$mt = microtime();
878
		echo "services_dnsupdate_process() being called $mt\n";
879
	}
880

    
881
	/* Dynamic DNS updating active? */
882
	if (isset($config['dnsupdate']['enable'])) {
883

    
884
		$wanip = get_current_wan_address();
885
		if ($wanip) {
886

    
887
			$keyname = $config['dnsupdate']['keyname'];
888
			/* trailing dot */
889
			if (substr($keyname, -1) != ".")
890
				$keyname .= ".";
891

    
892
			$hostname = $config['dnsupdate']['host'];
893
			/* trailing dot */
894
			if (substr($hostname, -1) != ".")
895
				$hostname .= ".";
896

    
897
			/* write private key file
898
			   this is dumb - public and private keys are the same for HMAC-MD5,
899
			   but nsupdate insists on having both */
900
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.private", "w");
901
			$privkey .= <<<EOD
902
Private-key-format: v1.2
903
Algorithm: 157 (HMAC)
904
Key: {$config['dnsupdate']['keydata']}
905

    
906
EOD;
907
			fwrite($fd, $privkey);
908
			fclose($fd);
909

    
910
			/* write public key file */
911
			if ($config['dnsupdate']['keytype'] == "zone") {
912
				$flags = 257;
913
				$proto = 3;
914
			} else if ($config['dnsupdate']['keytype'] == "host") {
915
				$flags = 513;
916
				$proto = 3;
917
			} else if ($config['dnsupdate']['keytype'] == "user") {
918
				$flags = 0;
919
				$proto = 2;
920
			}
921

    
922
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.key", "w");
923
			fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$config['dnsupdate']['keydata']}\n");
924
			fclose($fd);
925

    
926
			/* generate update instructions */
927
			$upinst =  "update delete {$config['dnsupdate']['host']} A\n";
928
			$upinst .= "update add {$config['dnsupdate']['host']} {$config['dnsupdate']['ttl']} A {$wanip}\n";
929
			$upinst .= "\n";	/* mind that trailing newline! */
930

    
931
			$fd = fopen("{$g['varetc_path']}/nsupdatecmds", "w");
932
			fwrite($fd, $upinst);
933
			fclose($fd);
934

    
935
			/* invoke nsupdate */
936
			$cmd = "/usr/sbin/nsupdate -k {$g['varetc_path']}/K{$keyname}+157+00000.key";
937
			if (isset($config['dnsupdate']['usetcp']))
938
				$cmd .= " -v";
939
			$cmd .= " {$g['varetc_path']}/nsupdatecmds";
940

    
941
			mwexec_bg($cmd);
942
		}
943
	}
944

    
945
	return 0;
946
}
947

    
948
function setup_wireless_olsr() {
949
	global $config, $g;
950
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
951
		return;
952
	if(isset($config['system']['developerspew'])) {
953
		$mt = microtime();
954
		echo "setup_wireless_olsr($interface) being called $mt\n";
955
	}
956
	conf_mount_rw();
957
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
958
		$olsr_enable = $olsrd['enable'];
959
		if($olsr_enable <> "on")
960
			return;
961
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
962

    
963
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
964
			$enableannounce .= "\nHna4\n";
965
			$enableannounce .= "{\n";
966
		if($olsrd['announcedynamicroute'])
967
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
968
		if($olsrd['enableannounce'] == "on")
969
			$enableannounce .= "0.0.0.0 0.0.0.0";
970
			$enableannounce .= "\n}\n";
971
		} else {
972
			$enableannounce = "";
973
		}
974

    
975
		$olsr .= <<<EODA
976
#
977
# olsr.org OLSR daemon config file
978
#
979
# Lines starting with a # are discarded
980
#
981
# This file was generated by setup_wireless_olsr() in services.inc
982
#
983

    
984
# This file is an example of a typical
985
# configuration for a mostly static
986
# network(regarding mobility) using
987
# the LQ extention
988

    
989
# Debug level(0-9)
990
# If set to 0 the daemon runs in the background
991

    
992
DebugLevel	2
993

    
994
# IP version to use (4 or 6)
995

    
996
IpVersion	4
997

    
998
# Clear the screen each time the internal state changes
999

    
1000
ClearScreen     yes
1001

    
1002
{$enableannounce}
1003

    
1004
# Should olsrd keep on running even if there are
1005
# no interfaces available? This is a good idea
1006
# for a PCMCIA/USB hotswap environment.
1007
# "yes" OR "no"
1008

    
1009
AllowNoInt	yes
1010

    
1011
# TOS(type of service) value for
1012
# the IP header of control traffic.
1013
# If not set it will default to 16
1014

    
1015
#TosValue	16
1016

    
1017
# The fixed willingness to use(0-7)
1018
# If not set willingness will be calculated
1019
# dynamically based on battery/power status
1020
# if such information is available
1021

    
1022
#Willingness    	4
1023

    
1024
# Allow processes like the GUI front-end
1025
# to connect to the daemon.
1026

    
1027
IpcConnect
1028
{
1029
     # Determines how many simultaneously
1030
     # IPC connections that will be allowed
1031
     # Setting this to 0 disables IPC
1032

    
1033
     MaxConnections  0
1034

    
1035
     # By default only 127.0.0.1 is allowed
1036
     # to connect. Here allowed hosts can
1037
     # be added
1038

    
1039
     Host            127.0.0.1
1040
     #Host            10.0.0.5
1041

    
1042
     # You can also specify entire net-ranges
1043
     # that are allowed to connect. Multiple
1044
     # entries are allowed
1045

    
1046
     #Net             192.168.1.0 255.255.255.0
1047
}
1048

    
1049
# Wether to use hysteresis or not
1050
# Hysteresis adds more robustness to the
1051
# link sensing but delays neighbor registration.
1052
# Used by default. 'yes' or 'no'
1053

    
1054
UseHysteresis	no
1055

    
1056
# Hysteresis parameters
1057
# Do not alter these unless you know
1058
# what you are doing!
1059
# Set to auto by default. Allowed
1060
# values are floating point values
1061
# in the interval 0,1
1062
# THR_LOW must always be lower than
1063
# THR_HIGH.
1064

    
1065
#HystScaling	0.50
1066
#HystThrHigh	0.80
1067
#HystThrLow	0.30
1068

    
1069

    
1070
# Link quality level
1071
# 0 = do not use link quality
1072
# 1 = use link quality for MPR selection
1073
# 2 = use link quality for MPR selection and routing
1074
# Defaults to 0
1075

    
1076
LinkQualityLevel	{$olsrd['enablelqe']}
1077

    
1078
# Link quality window size
1079
# Defaults to 10
1080

    
1081
LinkQualityWinSize	10
1082

    
1083
# Polling rate in seconds(float).
1084
# Default value 0.05 sec
1085

    
1086
Pollrate	0.05
1087

    
1088

    
1089
# TC redundancy
1090
# Specifies how much neighbor info should
1091
# be sent in TC messages
1092
# Possible values are:
1093
# 0 - only send MPR selectors
1094
# 1 - send MPR selectors and MPRs
1095
# 2 - send all neighbors
1096
#
1097
# defaults to 0
1098

    
1099
TcRedundancy	2
1100

    
1101
#
1102
# MPR coverage
1103
# Specifies how many MPRs a node should
1104
# try select to reach every 2 hop neighbor
1105
#
1106
# Can be set to any integer >0
1107
#
1108
# defaults to 1
1109

    
1110
MprCoverage	3
1111

    
1112
# Example plugin entry with parameters:
1113

    
1114
EODA;
1115

    
1116
if($olsrd['enablehttpinfo'] == "on") {
1117
	$olsr .= <<<EODB
1118

    
1119
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1120
{
1121
    PlParam     "port"   "{$olsrd['port']}"
1122
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1123
}
1124

    
1125
EODB;
1126

    
1127
}
1128

    
1129
if($olsrd['enabledsecure'] == "on") {
1130
	$olsr .= <<<EODC
1131

    
1132
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1133
{
1134
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1135
}
1136

    
1137
EODC;
1138

    
1139
}
1140

    
1141
if($olsrd['enabledyngw'] == "on") {
1142

    
1143
	/* unset default route, olsr auto negotiates */
1144
	mwexec("/sbin/route delete default");
1145

    
1146
	$olsr .= <<<EODE
1147

    
1148
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1149
{
1150
    # how often to look for a inet gw, in seconds
1151
    # defaults to 5 secs, if commented out
1152
    PlParam     "Interval"   "{$olsrd['polling']}"
1153

    
1154
    # if one or more IPv4 addresses are given, do a ping on these in
1155
    # descending order to validate that there is not only an entry in
1156
    # routing table, but also a real internet connection. If any of
1157
    # these addresses could be pinged successfully, the test was
1158
    # succesful, i.e. if the ping on the 1st address was successful,the
1159
    # 2nd won't be pinged
1160
    PlParam     "Ping"       "{$olsrd['ping']}"
1161
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1162
}
1163

    
1164
EODE;
1165

    
1166
}
1167

    
1168
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1169
	$interfaces = explode(',', $conf['iface_array']);
1170
	foreach($interfaces as $interface) {
1171
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1172
$olsr .= <<<EODAD
1173
Interface "{$realinterface}"
1174
{
1175

    
1176
    # Hello interval in seconds(float)
1177
    HelloInterval    2.0
1178

    
1179
    # HELLO validity time
1180
    HelloValidityTime	20.0
1181

    
1182
    # TC interval in seconds(float)
1183
    TcInterval        5.0
1184

    
1185
    # TC validity time
1186
    TcValidityTime	30.0
1187

    
1188
    # MID interval in seconds(float)
1189
    MidInterval	5.0
1190

    
1191
    # MID validity time
1192
    MidValidityTime	30.0
1193

    
1194
    # HNA interval in seconds(float)
1195
    HnaInterval	5.0
1196

    
1197
    # HNA validity time
1198
    HnaValidityTime 	30.0
1199

    
1200
    # When multiple links exist between hosts
1201
    # the weight of interface is used to determine
1202
    # the link to use. Normally the weight is
1203
    # automatically calculated by olsrd based
1204
    # on the characteristics of the interface,
1205
    # but here you can specify a fixed value.
1206
    # Olsrd will choose links with the lowest value.
1207

    
1208
    # Weight 0
1209

    
1210

    
1211
}
1212

    
1213
EODAD;
1214

    
1215
	}
1216
	break;
1217
}
1218
		fwrite($fd, $olsr);
1219
		fclose($fd);
1220
	}
1221

    
1222
	if(is_process_running("olsrd"))
1223
		mwexec("/usr/bin/killall olsrd");
1224

    
1225
	sleep(2);
1226

    
1227
	mwexec_bg("/usr/local/sbin/olsrd -f {$g['varetc_path']}/olsr.conf");
1228

    
1229
	conf_mount_ro();
1230
}
1231

    
1232
/* configure cron service */
1233
function configure_cron() {
1234
	global $g, $config;
1235
	conf_mount_rw();
1236
	/* preserve existing crontab entries */
1237
	$crontab_contents = file_get_contents("/etc/crontab");
1238
	$crontab_contents_a = split("\n", $crontab_contents);
1239
	
1240
	for ($i = 0; $i < count($crontab_contents_a); $i++) {
1241
		$item =& $crontab_contents_a[$i];
1242
		if (strpos($item, "# pfSense specific crontab entries") !== false) {
1243
			array_splice($crontab_contents_a, $i - 1);
1244
			break;
1245
		}
1246
	}
1247
	$crontab_contents = implode("\n", $crontab_contents_a) . "\n";
1248
	
1249
	
1250
	if (is_array($config['cron']['item'])) {
1251
		$crontab_contents .= "#\n";
1252
		$crontab_contents .= "# pfSense specific crontab entries\n";
1253
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1254
		$crontab_contents .= "#\n";
1255

    
1256
		foreach ($config['cron']['item'] as $item) {
1257
			$crontab_contents .= "\n{$item['minute']}\t";
1258
			$crontab_contents .= "{$item['hour']}\t";
1259
			$crontab_contents .= "{$item['mday']}\t";
1260
			$crontab_contents .= "{$item['month']}\t";
1261
			$crontab_contents .= "{$item['wday']}\t";
1262
			$crontab_contents .= "{$item['who']}\t";
1263
			$crontab_contents .= "{$item['command']}";
1264
		}
1265
    
1266
		$crontab_contents .= "\n#\n";
1267
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1268
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1269
		$crontab_contents .= "#\n\n";
1270
	}
1271
	
1272
	/* please maintain the newline at the end of file */
1273
	file_put_contents("/etc/crontab", $crontab_contents);
1274
	
1275
	if (!$g['booting'])
1276
		conf_mount_ro();
1277
}
1278

    
1279
function upnp_action ($action) {
1280
	switch($action) {
1281
		case "start":
1282
			if(file_exists('/var/etc/miniupnpd.conf'))
1283
				mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf');
1284
			break;
1285
		case "stop":
1286
			while((int)exec("pgrep miniupnpd | wc -l") > 0)
1287
				mwexec('killall miniupnpd 2>/dev/null');
1288
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1289
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1290
			break;
1291
		case "restart":
1292
			upnp_action('stop');
1293
			upnp_action('start');
1294
			break;
1295
	}
1296
}
1297

    
1298
function upnp_start() {
1299
	global $config, $g;
1300
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1301
		if($g['booting']) {
1302
			echo "Starting UPnP service...";
1303
			include('/usr/local/pkg/miniupnpd.inc');
1304
			sync_package_miniupnpd();
1305
			echo "done.\n";
1306
		}
1307
		else {
1308
			upnp_action('start');
1309
		}
1310
	}
1311
}
1312

    
1313
?>
(18-18/27)