Project

General

Profile

Download (48.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services.inc
5
	part of the pfSense project (http://www.pfsense.com)
6

    
7
	originally part of m0n0wall (http://m0n0.ch/wall)
8
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
9
	Copyright (C) 2010	Ermal Lu?i
10
	All rights reserved.
11

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

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

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

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

    
34
/*
35
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/bin/pgrep	/bin/sh	/usr/local/sbin/dhcpd	/usr/local/sbin/igmpproxy
36
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/usr/sbin/arp	/sbin/ifconfig	/usr/local/sbin/dnsmasq
37
	pfSense_BUILDER_BINARIES:	/usr/sbin/bsnmpd	/sbin/route	/usr/local/sbin/olsrd
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/miniupnpd	/usr/sbin/rtadvd
39
	pfSense_MODULE:	utils
40
*/
41

    
42
/* implement ipv6 route advertising deamon */
43
function services_rtadvd_configure() {
44
	global $config, $g;
45
	
46
	if(isset($config['system']['developerspew'])) {
47
		$mt = microtime();
48
		echo "services_rtadvd_configure() being called $mt\n";
49
	}
50

    
51
	if(is_process_running("rtadvd")) {
52
		mwexec("killall -9 rtadvd", true);
53
	}
54

    
55
	if (!is_array($config['dhcpdv6']))
56
		$config['dhcpdv6'] = array();
57

    
58
	$dhcpdv6cfg = $config['dhcpdv6'];
59
	$Iflist = get_configured_interface_list();
60

    
61
	/* write rtadvd.conf */
62
	$fd = fopen("{$g['varetc_path']}/rtadvd.conf", "w");
63
	if (!$fd) {
64
		printf("Error: cannot open rtadvd.conf in services_rtadvd_configure().\n");
65
		return 1;
66
	}
67

    
68
	/* raflags, other o, managed=64 m, stateful=128, both=192 */
69

    
70
	$rtadvdconf = "# Automatically Generated, do not edit\n";
71
	$rtadvdconf = <<<EOD
72

    
73
#
74
# common definitions.
75
#
76
default:\
77
        :raflags#0:rltime#3600:\
78
        :vltime#360000:pltime#360000:mtu#1500:
79
ether:\
80
        :mtu#1280:tc=default:
81

    
82
EOD;
83

    
84
	/* Process all links which need the router advertise daemon */
85
	$rtadvdnum = 0;
86
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
87
		if($dhcpv6ifconf['mode'] == "disabled")
88
			continue;
89

    
90
		$realif = get_real_interface($dhcpv6if);
91
		$rtadvdifs[] = $realif;
92

    
93
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
94
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
95
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
96
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
97

    
98
		$rtadvdconf .= "# Generated for DHCPv6 Server $dhcpv6if\n";
99
		$rtadvdconf .= "{$realif}:\\\n";
100
		$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
101
		$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
102
		switch($dhcpv6ifconf['mode']) {
103
			case "managed":
104
				$rtadvdconf .= "\t:raflags=\"m\":\\\n";
105
				break;
106
			case "assist":
107
				$rtadvdconf .= "\t:raflags=\"mo\":\\\n";
108
				break;
109
			default:
110
				$rtadvdconf .= "\t:raflags#0:\\\n";
111
				break;				
112

    
113
		}
114
		$rtadvdconf .= "\t:tc=ether:\n";
115
		$rtadvdconf .= "\n\n";
116
		$rtadvdnum++;
117
	}
118

    
119
	foreach ($Iflist as $if => $ifdescr) {
120
		if(!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id']))
121
			continue;
122

    
123
		$realif = get_real_interface($if);
124
		$rtadvdifs[] = $realif;
125

    
126
		$ifcfgipv6 = get_interface_ipv6($if);
127
		$ifcfgsnv6 = get_interface_subnetv6($if);
128
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
129
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
130

    
131
		if(is_ipaddrv6($subnetv6)) {
132
			$rtadvdconf .= "# Generated for DHCP-PD delegation $if\n";
133
			$rtadvdconf .= "{$realif}:\\\n";
134
			$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
135
			$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
136
			$rtadvdconf .= "\t:raflags=\"mo\":\\\n";
137
			$rtadvdconf .= "\t:tc=ether:\n";
138
			$rtadvdconf .= "\n\n"; 
139
			$rtadvdnum++;
140
		}
141
	}
142

    
143
	fwrite($fd, $rtadvdconf);
144
	fclose($fd);
145

    
146
	if(count($rtadvdifs) > 0) {
147
		mwexec("/usr/sbin/rtadvd -c {$g['varetc_path']}/rtadvd.conf " . join(" ", $rtadvdifs));
148
	}
149
	return 0;
150
}
151

    
152
function services_dhcpd_configure() {
153
	global $config, $g;
154

    
155
	/* configure DHCPD chroot once */
156
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
157
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
158
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
159
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
160
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
161
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
162
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
163
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
164
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
165
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
166
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
167
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
168
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
169
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
170
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
171
	if(!trim($status))
172
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
173
	fclose($fd);
174
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
175

    
176
	services_dhcpdv4_configure();
177
	services_dhcpdv6_configure();
178
	services_rtadvd_configure();
179
	return;
180

    
181
}
182
function services_dhcpdv4_configure() {
183
	global $config, $g;
184
	
185
	if($g['services_dhcp_server_enable'] == false) 
186
		return;
187

    
188
	if(isset($config['system']['developerspew'])) {
189
		$mt = microtime();
190
		echo "services_dhcpdv4_configure($if) being called $mt\n";
191
	}
192
	
193
	/* kill any running dhcpd */
194
	if(is_process_running("dhcpd")) {
195
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
196
	}
197

    
198
	/* DHCP enabled on any interfaces? */
199
	if (!is_dhcp_server_enabled())
200
		return 0;
201

    
202
	/* if OLSRD is enabled, allow WAN to house DHCP. */
203
	if($config['installedpackages']['olsrd'])
204
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
205
				if($olsrd['enable'])
206
					$is_olsr_enabled = true;
207

    
208
	if ($g['booting']) {
209
		if ($g['platform'] != "pfSense") {
210
			/* restore the leases, if we have them */
211
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
212
				$dhcprestore = "";
213
				$dhcpreturn = "";
214
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
215
				$dhcprestore = implode(" ", $dhcprestore);
216
				if($dhcpreturn <> 0) {
217
					log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n"));
218
				}
219
			}
220
		}
221
	}
222

    
223
	$syscfg = $config['system'];
224
	if (!is_array($config['dhcpd']))
225
		$config['dhcpd'] = array();
226
	$dhcpdcfg = $config['dhcpd'];
227
	$Iflist = get_configured_interface_list();
228
		
229
	if ($g['booting'])
230
		echo gettext("Starting DHCP service...");
231
	else
232
		sleep(1);
233

    
234
	/* write dhcpd.conf */
235
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
236
	if (!$fd) {
237
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
238
		return 1;
239
	}
240

    
241
	$custoptions = "";
242
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
243
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
244
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
245
				if(!empty($item['type']))
246
					$itemtype = $item['type'];
247
				else
248
					$itemtype = "text";
249
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
250
			}
251
		}
252
	}
253

    
254
	$dhcpdconf = <<<EOD
255
	
256
option domain-name "{$syscfg['domain']}";
257
option ldap-server code 95 = text;
258
option domain-search-list code 119 = text;
259
{$custoptions}
260
default-lease-time 7200;
261
max-lease-time 86400;
262
log-facility local7;
263
ddns-update-style none;
264
one-lease-per-client true;
265
deny duplicates;
266
ping-check true;
267

    
268
EOD;
269

    
270
	if(!isset($dhcpifconf['disableauthoritative']))
271
		$dhcpdconf .= "authoritative;\n";
272

    
273
	if(isset($dhcpifconf['alwaysbroadcast'])) 
274
		$dhcpdconf .= "always-broadcast on\n";
275

    
276
	$dhcpdifs = array();
277

    
278
	/*    loop through and determine if we need to setup
279
	 *    failover peer "bleh" entries
280
	 */
281
	$dhcpnum = 0;
282
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
283

    
284
		interfaces_staticarp_configure($dhcpif);
285

    
286
		if (!isset($dhcpifconf['enable']))
287
			continue;
288

    
289
		if($dhcpifconf['failover_peerip'] <> "") {
290
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
291
			$intip = find_interface_ip($int);
292
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
293
			/*
294
			 *    yep, failover peer is defined.
295
			 *    does it match up to a defined vip?
296
			 */
297
			$skew = 110;
298
			$a_vip = &$config['virtualip']['vip'];
299
			if(is_array($a_vip)) {
300
				foreach ($a_vip as $vipent) {
301
					if($int == $real_dhcpif) {
302
						/* this is the interface! */
303
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
304
							$skew = 0;
305
					}
306
				}
307
			} else {
308
				log_error(gettext("Warning!  DHCP Failover setup and no CARP virtual IP's defined!"));
309
			}
310
			if($skew > 10) {
311
				$type = "secondary";
312
				$dhcpdconf_pri  = "mclt 600;\n";
313
				$my_port = "520";
314
				$peer_port = "519";
315
			} else {
316
				$my_port = "519";
317
				$peer_port = "520";
318
				$type = "primary";
319
				$dhcpdconf_pri  = "split 128;\n";
320
				$dhcpdconf_pri .= "  mclt 600;\n";
321
			}
322
			$dhcpdconf .= <<<EOPP
323
failover peer "dhcp{$dhcpnum}" {
324
  {$type};
325
  address {$intip};
326
  port {$my_port};
327
  peer address {$dhcpifconf['failover_peerip']};
328
  peer port {$peer_port};
329
  max-response-delay 10;
330
  max-unacked-updates 10;
331
  {$dhcpdconf_pri}
332
  load balance max seconds 3;
333
}
334

    
335
EOPP;
336
		$dhcpnum++;
337
		}
338
	}
339

    
340
	$dhcpnum = 0;
341

    
342
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
343

    
344
		$ifcfg = $config['interfaces'][$dhcpif];
345

    
346
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
347
			continue;
348
		$ifcfgip = get_interface_ip($dhcpif);
349
		$ifcfgsn = get_interface_subnet($dhcpif);
350
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
351
		$subnetmask = gen_subnet_mask($ifcfgsn);
352

    
353
		if (!is_ipaddr($subnet))
354
			continue;
355

    
356
		if($is_olsr_enabled == true)
357
			if($dhcpifconf['netmask'])
358
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
359

    
360
		$dnscfg = "";
361

    
362
		if ($dhcpifconf['domain']) {
363
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
364
		}
365
		
366
    		if($dhcpifconf['domainsearchlist'] <> "") {
367
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
368
    		}
369

    
370
		if (isset($dhcpifconf['ddnsupdate'])) {
371
			if($dhcpifconf['ddnsdomain'] <> "") {
372
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
373
			}
374
			$dnscfg .= "	ddns-update-style interim;\n";
375
		}
376

    
377
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
378
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
379
		} else if (isset($config['dnsmasq']['enable'])) {
380
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
381
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
382
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
383
		}
384

    
385
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
386
		$dhcpdconf .= "	pool {\n";
387

    
388
		/* is failover dns setup? */
389
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
390
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
391
			if($dhcpifconf['dnsserver'][1] <> "")
392
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
393
			$dhcpdconf .= ";\n";
394
		}
395

    
396
		if($dhcpifconf['failover_peerip'] <> "")
397
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
398

    
399
		if (isset($dhcpifconf['denyunknown']))
400
		   $dhcpdconf .= "		deny unknown-clients;\n";
401

    
402
		if ($dhcpifconf['gateway'])
403
			$routers = $dhcpifconf['gateway'];
404
		else
405
			$routers = $ifcfgip;
406

    
407
		if($dhcpifconf['failover_peerip'] <> "") {
408
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
409
			$dhcpnum++;
410
		}
411

    
412
		$dhcpdconf .= <<<EOD
413
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
414
	}
415
	option routers {$routers};
416
$dnscfg
417

    
418
EOD;
419
    		// default-lease-time
420
		if ($dhcpifconf['defaultleasetime'])
421
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
422

    
423
		// max-lease-time
424
		if ($dhcpifconf['maxleasetime'])
425
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
426

    
427
		// netbios-name*
428
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
429
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
430
			$dhcpdconf .= "	option netbios-node-type 8;\n";
431
		}
432

    
433
		// ntp-servers
434
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
435
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
436

    
437
		// tftp-server-name
438
		if ($dhcpifconf['tftp'] <> "")
439
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
440

    
441
		// Handle option, number rowhelper values
442
		$dhcpdconf .= "\n";
443
		if($dhcpifconf['numberoptions']['item']) {
444
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
445
				if(empty($item['type']) || $item['type'] == "text")
446
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
447
				else
448
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
449
			}
450
		}
451

    
452
		// ldap-server
453
		if ($dhcpifconf['ldap'] <> "")
454
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
455

    
456
		// net boot information
457
		if(isset($dhcpifconf['netboot'])) {
458
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
459
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
460
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
461
			}
462
			if ($dhcpifconf['rootpath'] <> "") {
463
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
464
      		}
465
		}
466
		
467
		$dhcpdconf .= <<<EOD
468
}
469

    
470
EOD;
471

    
472
		/* add static mappings */
473
		if (is_array($dhcpifconf['staticmap'])) {
474

    
475
			$i = 0;
476
			foreach ($dhcpifconf['staticmap'] as $sm) {
477
				$dhcpdconf .= <<<EOD
478
host s_{$dhcpif}_{$i} {
479
	hardware ethernet {$sm['mac']};
480

    
481
EOD;
482
				if ($sm['ipaddr'])
483
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
484

    
485
				if ($sm['hostname']) {
486
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
487
					$dhhostname = str_replace(".", "_", $dhhostname);
488
					$dhcpdconf .= "	option host-name {$dhhostname};\n";
489
				}
490
				if ($sm['netbootfile'])
491
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
492

    
493
				$dhcpdconf .= "}\n";
494
				$i++;
495
			}
496
		}
497

    
498
		$dhcpdifs[] = get_real_interface($dhcpif);
499
	}
500

    
501
	fwrite($fd, $dhcpdconf);
502
	fclose($fd);
503

    
504
	/* create an empty leases database */
505
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
506
	
507

    
508
	/* fire up dhcpd in a chroot */
509
	if(count($dhcpdifs) > 0) {
510
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
511
			join(" ", $dhcpdifs));
512
	}
513

    
514
	if ($g['booting']) {
515
		print "done.\n";
516
	}
517

    
518
	return 0;
519
}
520

    
521
function services_dhcpdv6_configure() {
522
	global $config, $g;
523
	
524
	if($g['services_dhcp_server_enable'] == false) 
525
		return;
526

    
527
	if(isset($config['system']['developerspew'])) {
528
		$mt = microtime();
529
		echo "services_dhcpd_configure($if) being called $mt\n";
530
	}
531
	
532
	/* kill any running dhcpd */
533
	if(is_process_running("dhcpd")) {
534
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
535
	}
536

    
537
	/* DHCP enabled on any interfaces? */
538
	if (!is_dhcp_server_enabled())
539
		return 0;
540

    
541
	/* if OLSRD is enabled, allow WAN to house DHCP. */
542
	if($config['installedpackages']['olsrd'])
543
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
544
				if($olsrd['enable'])
545
					$is_olsr_enabled = true;
546

    
547
	if ($g['booting']) {
548
		if ($g['platform'] != "pfSense") {
549
			/* restore the leases, if we have them */
550
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
551
				$dhcprestore = "";
552
				$dhcpreturn = "";
553
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
554
				$dhcprestore = implode(" ", $dhcprestore);
555
				if($dhcpreturn <> 0) {
556
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
557
				}
558
			}
559
		}
560
	}
561

    
562
	$syscfg = $config['system'];
563
	if (!is_array($config['dhcpdv6']))
564
		$config['dhcpdv6'] = array();
565
	$dhcpdv6cfg = $config['dhcpdv6'];
566
	$Iflist = get_configured_interface_list();
567
		
568
	if ($g['booting'])
569
		echo "Starting DHCPv6 service...";
570
	else
571
		sleep(1);
572

    
573
	/* write dhcpdv6.conf */
574
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
575
	if (! $fdv6) {
576
		printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n");
577
		return 1;
578
	}
579

    
580
	$custoptionsv6 = "";
581
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {	
582
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
583
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
584
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
585
			}
586
		}
587
	}
588

    
589
	$dhcpdv6conf = <<<EOD
590
	
591
option domain-name "{$syscfg['domain']}";
592
option ldap-server code 95 = text;
593
option domain-search-list code 119 = text;
594
{$custoptions}
595
default-lease-time 7200;
596
max-lease-time 86400;
597
log-facility local7;
598
ddns-update-style none;
599
one-lease-per-client true;
600
deny duplicates;
601
ping-check true;
602

    
603
EOD;
604

    
605
	if(!isset($dhcpv6ifconf['disableauthoritative']))
606
		$dhcpdv6conf .= "authoritative;\n";
607

    
608
	if(isset($dhcpv6ifconf['alwaysbroadcast'])) 
609
		$dhcpdv6conf .= "always-broadcast on\n";
610

    
611
	$dhcpdv6ifs = array();
612

    
613
	/*    loop through and determine if we need to setup
614
	 *    failover peer "bleh" entries
615
	 */
616
	$dhcpv6num = 0;
617
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
618

    
619
		if (!isset($dhcpv6ifconf['enable']))
620
			continue;
621

    
622
		if($dhcpv6ifconf['failover_peerip'] <> "") {
623
			$intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']);
624
			$intipv6 = find_interface_ipv6($intv6);
625
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
626
			/*
627
			 *    yep, failover peer is defined.
628
			 *    does it match up to a defined vip?
629
			 */
630
			$skew = 110;
631
			$a_vip = &$config['virtualip']['vip'];
632
			if(is_array($a_vip)) {
633
				foreach ($a_vip as $vipent) {
634
					if($intv6 == $real_dhcpv6if) {
635
						/* this is the interface! */
636
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
637
							$skew = 0;
638
					}
639
				}
640
			} else {
641
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
642
			}
643
			if($skew > 10) {
644
				$typev6 = "secondary";
645
				$dhcpdv6conf_pri  = "mclt 600;\n";
646
				$my_portv6 = "520";
647
				$peer_portv6 = "519";
648
			} else {
649
				$my_portv6 = "519";
650
				$peer_portv6 = "520";
651
				$typev6 = "primary";
652
				$dhcpdv6conf_pri  = "split 128;\n";
653
				$dhcpdv6conf_pri .= "  mclt 600;\n";
654
			}
655
			$dhcpdv6conf .= <<<EOPP
656
failover peer "dhcpv6{$dhcpv6num}" {
657
  {$typev6};
658
  address {$intipv6};
659
  port {$my_portv6};
660
  peer address {$dhcpv6ifconf['failover_peerip']};
661
  peer port {$peer_portv6};
662
  max-response-delay 10;
663
  max-unacked-updates 10;
664
  {$dhcpdv6conf_pri}
665
  load balance max seconds 3;
666
}
667

    
668
EOPP;
669
		$dhcpv6num++;
670
		}
671
	}
672

    
673
	$dhcpv6num = 0;
674
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
675

    
676
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
677

    
678
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
679
			continue;
680
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
681
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
682
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
683
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
684

    
685
		if($is_olsr_enabled == true)
686
			if($dhcpv6ifconf['netmask'])
687
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
688

    
689
		$dnscfgv6 = "";
690

    
691
		if ($dhcpv6ifconf['domain']) {
692
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
693
		}
694
		
695
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
696
			$dnscfgv6 .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
697
    		}
698

    
699
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
700
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
701
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
702
			}
703
			$dnscfgv6 .= "	ddns-update-style interim;\n";
704
		}
705

    
706
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
707
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
708
		} else if (isset($config['dnsmasq']['enable'])) {
709
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
710
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
711
			$dns_arrv6 = array();
712
			foreach($syscfg['dnsserver'] as $dnsserver) {
713
				if(is_ipaddrv6($dnsserver)) {
714
					$dns_arrv6[] = $dnsserver;
715
				}
716
			}
717
			if(!empty($dns_arrv6))
718
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
719
		}
720

    
721
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
722
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
723

    
724
		/* is failover dns setup? */
725
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
726
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
727
			if($dhcpv6ifconf['dnsserver'][1] <> "")
728
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
729
			$dhcpdv6conf .= ";\n";
730
		}
731

    
732
		if($dhcpv6ifconf['failover_peerip'] <> "")
733
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
734

    
735
		if (isset($dhcpv6ifconf['denyunknown']))
736
		   $dhcpdv6conf .= "		deny unknown clients;\n";
737

    
738
		if ($dhcpv6ifconf['gateway'])
739
			$routersv6 = $dhcpv6ifconf['gateway'];
740
		else
741
			$routersv6 = $ifcfgipv6;
742

    
743
		if($dhcpv6ifconf['failover_peerip'] <> "") {
744
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
745
			$dhcpv6num++;
746
		}
747

    
748
		$dhcpdv6conf .= <<<EOD
749
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
750
	# Not supported in IPv6; option dhcp6.routers {$routersv6};
751
$dnscfgv6
752

    
753
EOD;
754

    
755
		if(is_ipaddrv6($dhcpv6ifconf['prefixrange']['from']) && is_ipaddrv6($dhcpv6ifconf['prefixrange']['to'])) {
756
			$dhcpdv6conf .= "	prefix6 {$dhcpv6ifconf['prefixrange']['from']} {$dhcpv6ifconf['prefixrange']['to']}/{$dhcpv6ifconf['prefixrange']['prefixlength']};\n";
757

    
758
		}
759
    		// default-lease-time
760
		if ($dhcpv6ifconf['defaultleasetime'])
761
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
762

    
763
		// max-lease-time
764
		if ($dhcpv6ifconf['maxleasetime'])
765
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
766

    
767
		// ntp-servers
768
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0])
769
			$dhcpdv6conf .= "	option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
770

    
771
		// tftp-server-name
772
		if ($dhcpv6ifconf['tftp'] <> "")
773
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
774

    
775
		// Handle option, number rowhelper values
776
		$dhcpdv6conf .= "\n";
777
		if($dhcpv6ifconf['numberoptions']['item']) {
778
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
779
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
780
			}
781
		}
782

    
783
		// ldap-server
784
		if ($dhcpv6ifconf['ldap'] <> "")
785
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
786

    
787
		// net boot information
788
		if(isset($dhcpv6ifconf['netboot'])) {
789
			if (($dhcpv6ifconf['next-server'] <> "") && ($dhcpv6ifconf['filename'] <> "")) {
790
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['next-server']};\n";
791
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
792
			}
793
			if ($dhcpv6ifconf['rootpath'] <> "") {
794
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
795
      		}
796
	}
797
		
798
		$dhcpdv6conf .= <<<EOD
799
}
800
EOD;
801

    
802
		/* add static mappings */
803
		/* Needs to use DUID */
804
		if (is_array($dhcpv6ifconf['staticmap'])) {
805

    
806
			$i = 0;
807
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
808
				$dhcpdv6conf .= <<<EOD
809
host s_{$dhcpv6if}_{$i} {
810
	host-identifier option dhcp6.client-id {$sm['duid']};
811

    
812
EOD;
813
				if ($sm['ipaddrv6'])
814
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
815

    
816
				if ($sm['hostname']) {
817
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
818
					$dhhostname = str_replace(".", "_", $dhhostname);
819
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
820
				}
821
				if ($sm['netbootfile'])
822
					$dhcpdv6conf .= "	filename \"{$sm['netbootfile']}\";\n";
823

    
824
				$dhcpdv6conf .= "}\n";
825
				$i++;
826
			}
827
		}
828
		
829
		if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") {
830
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
831
			$dhcpdv6ifs[] = $realif;
832
			exec("/sbin/ifconfig {$realif} |awk  '/ether/ {print $2}'", $mac);
833
			$v6address = generate_ipv6_from_mac($mac[0]);
834
			/* Create link local address for bridges */
835
			if(stristr("$realif", "bridge")) {
836
				mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
837
			}
838
		}
839
	}
840

    
841
	fwrite($fdv6, $dhcpdv6conf);
842
	fclose($fdv6);
843
	/* create an empty leases v6 database */
844
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
845
	
846

    
847
	/* fire up dhcpd in a chroot */
848
	if(count($dhcpdv6ifs) > 0) {
849
		mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf -pf {$g['varrun_path']}/dhcpdv6.pid " .
850
			join(" ", $dhcpdv6ifs));
851
	}
852

    
853
	if ($g['booting']) {
854
		print gettext("done.") . "\n";
855
	}
856

    
857
	return 0;
858
}
859

    
860
function services_igmpproxy_configure() {
861
        global $config, $g;
862

    
863
        /* kill any running igmpproxy */
864
        killbyname("igmpproxy");
865

    
866
	if (!is_array($config['igmpproxy']['igmpentry']))
867
		return 1;
868

    
869
        $iflist = get_configured_interface_list();
870

    
871
        $igmpconf = <<<EOD
872

    
873
##------------------------------------------------------
874
## Enable Quickleave mode (Sends Leave instantly)
875
##------------------------------------------------------
876
quickleave
877

    
878
EOD;
879

    
880
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
881
                unset($iflist[$igmpcf['ifname']]);
882
                $realif = get_real_interface($igmpcf['ifname']);
883
                if (empty($igmpcf['threshold']))
884
                        $threshld = 1;
885
                else
886
                        $threshld = $igmpcf['threshold'];
887
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
888

    
889
                if ($igmpcf['address'] <> "") {
890
                        $item = explode(" ", $igmpcf['address']);
891
                        foreach($item as $iww)
892
                                $igmpconf .= "altnet {$iww}\n";
893
                }
894
                $igmpconf .= "\n";
895
        }
896
        foreach ($iflist as $ifn) {
897
                $realif = get_real_interface($ifn);
898
                $igmpconf .= "phyint {$realif} disabled\n";
899
        }
900
	$igmpconf .= "\n";
901

    
902
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
903
        if (!$igmpfl) {
904
                log_error(gettext("Could not write Igmpproxy configuration file!"));
905
                return;
906
        }
907
        fwrite($igmpfl, $igmpconf);
908
        fclose($igmpfl);
909

    
910
        mwexec("/usr/local/sbin/igmpproxy -c " . $g['tmp_path'] . "/igmpproxy.conf");
911
        log_error(gettext("Started Igmpproxy service sucsesfully."));
912

    
913
        return 0;
914
}
915

    
916
function services_dhcrelay_configure() {
917
	global $config, $g;
918
	if(isset($config['system']['developerspew'])) {
919
		$mt = microtime();
920
		echo "services_dhcrelay_configure() being called $mt\n";
921
	}
922

    
923
	/* kill any running dhcrelay */
924
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
925

    
926
	$dhcrelaycfg =& $config['dhcrelay'];
927

    
928
	/* DHCPRelay enabled on any interfaces? */
929
	if (!isset($dhcrelaycfg['enable']))
930
		return 0;
931

    
932
	if ($g['booting'])
933
		echo gettext("Starting DHCP relay service...");
934
	else
935
		sleep(1);
936

    
937
	$iflist = get_configured_interface_list();
938

    
939
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
940
	foreach ($dhcifaces as $dhcrelayif) {
941
		if (!isset($iflist[$dhcrelayif]) ||
942
			link_interface_to_bridge($dhcrelayif))
943
			continue;
944

    
945
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
946
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
947
	}
948

    
949
	/* 
950
	 * In order for the relay to work, it needs to be active
951
	 * on the interface in which the destination server sits.
952
	 */
953
	$srvips = explode(",", $dhcrelaycfg['server']);
954
	foreach ($srvips as $srcidx => $srvip) {
955
		unset($destif);
956
		foreach ($iflist as $ifname) {
957
			$subnet = get_interface_ip($ifname);
958
			if (!is_ipaddr($subnet))
959
				continue;
960
			$subnet .=  "/" . get_interface_subnet($ifname);
961
			if (ip_in_subnet($srvip, $subnet)) {
962
				$destif = get_real_interface($ifname);
963
				break;
964
			}
965
		}
966
		if (!isset($destif)) {
967
			if (is_array($config['staticroutes']['route'])) {
968
				foreach ($config['staticroutes']['route'] as $rtent) {
969
					if (ip_in_subnet($srvip, $rtent['network'])) {
970
						$a_gateways = return_gateways_array(true);
971
						$destif = $a_gateways[$rtent['gateway']]['interface'];
972
						break;
973
					}
974
				}
975
			}
976
		}
977

    
978
		if (!isset($destif)) {
979
			/* Create a array from the existing route table */
980
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
981
        		array_shift($route_str);
982
        		array_shift($route_str);
983
        		array_shift($route_str);
984
        		array_shift($route_str);
985
        		$route_arr = array();
986
        		foreach($route_str as $routeline) {
987
                		$items = preg_split("/[ ]+/i", $routeline);
988
				if (ip_in_subnet($srvip, $items[0])) {
989
					$destif = trim($items[6]);
990
					break;
991
				}
992
        		}
993
		}
994
	
995
		if (!isset($destif)) {
996
			if (is_array($config['gateways']['gateway_item'])) {
997
				foreach ($config['gateways']['gateway_item'] as $gateway) {
998
					if (isset($gateway['defaultgw'])) {
999
						$a_gateways = return_gateways_array(true);
1000
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1001
						break;
1002
					}		
1003
				}
1004
			} else
1005
				$destif = get_real_interface("wan");
1006
		}
1007

    
1008
		if (!empty($destif))
1009
			$dhcrelayifs[] = $destif;
1010
	}
1011
	$dhcrelayifs = array_unique($dhcrelayifs);
1012

    
1013
	/* fire up dhcrelay */
1014
	if (empty($dhcrelayifs)) {
1015
		log_error("No suitable interface found for running dhcrelay!");
1016
		return; /* XXX */
1017
	}
1018

    
1019
	$cmd = "/usr/local/sbin/dhcrelay -i " .  implode(" -i ", $dhcrelayifs);
1020

    
1021
	if (isset($dhcrelaycfg['agentoption']))
1022
		$cmd .=  " -a -m replace";
1023

    
1024
	$cmd .= " " . implode(" ", $srvips);
1025
	mwexec($cmd);
1026

    
1027
	return 0;
1028
}
1029

    
1030
function services_dyndns_configure_client($conf) {
1031

    
1032
	if (!isset($conf['enable']))
1033
		return;
1034

    
1035
	/* load up the dyndns.class */
1036
	require_once("dyndns.class");
1037

    
1038
	$dns = new updatedns($dnsService = $conf['type'],
1039
		$dnsHost = $conf['host'],
1040
		$dnsUser = $conf['username'],
1041
		$dnsPass = $conf['password'],
1042
		$dnsWilcard = $conf['wildcard'],
1043
		$dnsMX = $conf['mx'], 
1044
		$dnsIf = "{$conf['interface']}");
1045

    
1046
}
1047

    
1048
function services_dyndns_configure($int = "") {
1049
	global $config, $g;
1050
	if(isset($config['system']['developerspew'])) {
1051
		$mt = microtime();
1052
		echo "services_dyndns_configure() being called $mt\n";
1053
	}
1054

    
1055
	$dyndnscfg = $config['dyndnses']['dyndns'];
1056

    
1057
	if (is_array($dyndnscfg)) {
1058
		if ($g['booting']) 
1059
			echo gettext("Starting DynDNS clients...");
1060

    
1061
		foreach ($dyndnscfg as $dyndns) {
1062
			if (!empty($int) && $int != $dyndns['interface'])
1063
				continue;
1064

    
1065
			services_dyndns_configure_client($dyndns);
1066

    
1067
			sleep(1);
1068
		}
1069

    
1070
		if ($g['booting'])
1071
			echo gettext("done.") . "\n";
1072
	}
1073

    
1074
	return 0;
1075
}
1076

    
1077
function services_dnsmasq_configure() {
1078
	global $config, $g;
1079
	$return = 0;
1080
	
1081
	if(isset($config['system']['developerspew'])) {
1082
		$mt = microtime();
1083
		echo "services_dnsmasq_configure() being called $mt\n";
1084
	}
1085

    
1086
	/* kill any running dnsmasq */
1087
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1088

    
1089
	if (isset($config['dnsmasq']['enable'])) {
1090

    
1091
		if ($g['booting'])
1092
			echo gettext("Starting DNS forwarder...");
1093
		else
1094
			sleep(1);
1095

    
1096
		/* generate hosts file */
1097
		if(system_hosts_generate()!=0)
1098
			$return = 1;
1099

    
1100
		$args = "";
1101

    
1102
		if (isset($config['dnsmasq']['regdhcp'])) {
1103
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1104
		}
1105
		
1106
		/* Setup forwarded domains */
1107
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1108
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1109
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1110
			}
1111
		}
1112

    
1113
		/* Allow DNS Rebind for forwarded domains */
1114
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1115
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1116
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1117
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1118
				}
1119
			}
1120
		}
1121

    
1122
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1123
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1124

    
1125
		/* run dnsmasq */
1126
		mwexec("/usr/local/sbin/dnsmasq --local-ttl 1 --all-servers {$dns_rebind} --dns-forward-max=5000 --cache-size=10000 {$args}");
1127

    
1128
		if ($g['booting'])
1129
			echo gettext("done.") . "\n";
1130
	}
1131

    
1132
	if (!$g['booting']) {
1133
		if(services_dhcpd_configure()!=0)
1134
			$return = 1;
1135
	}
1136

    
1137
	return $return;
1138
}
1139

    
1140
function services_snmpd_configure() {
1141
	global $config, $g;
1142
	if(isset($config['system']['developerspew'])) {
1143
		$mt = microtime();
1144
		echo "services_snmpd_configure() being called $mt\n";
1145
	}
1146

    
1147
	/* kill any running snmpd */
1148
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1149
	sleep(2);
1150
	if(is_process_running("bsnmpd")) 
1151
		mwexec("/usr/bin/killall bsnmpd", true);
1152

    
1153
	if (isset($config['snmpd']['enable'])) {
1154

    
1155
		if ($g['booting'])
1156
			echo gettext("Starting SNMP daemon... ");
1157

    
1158
		/* generate snmpd.conf */
1159
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1160
		if (!$fd) {
1161
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1162
			return 1;
1163
		}
1164

    
1165

    
1166
		$snmpdconf = <<<EOD
1167
location := "{$config['snmpd']['syslocation']}"
1168
contact := "{$config['snmpd']['syscontact']}"
1169
read := "{$config['snmpd']['rocommunity']}"
1170

    
1171
EOD;
1172

    
1173
/* No docs on what write strings do there for disable for now.
1174
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1175
		    $snmpdconf .= <<<EOD
1176
# write string
1177
write := "{$config['snmpd']['rwcommunity']}"
1178

    
1179
EOD;
1180
		}
1181
*/
1182

    
1183

    
1184
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1185
		    $snmpdconf .= <<<EOD
1186
# SNMP Trap support.
1187
traphost := {$config['snmpd']['trapserver']}
1188
trapport := {$config['snmpd']['trapserverport']}
1189
trap := "{$config['snmpd']['trapstring']}"
1190

    
1191

    
1192
EOD;
1193
		}
1194

    
1195

    
1196
		$snmpdconf .= <<<EOD
1197
system := 1     # pfSense
1198
%snmpd
1199
begemotSnmpdDebugDumpPdus       = 2
1200
begemotSnmpdDebugSyslogPri      = 7
1201
begemotSnmpdCommunityString.0.1 = $(read)
1202

    
1203
EOD;
1204

    
1205
/* No docs on what write strings do there for disable for now.
1206
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1207
		    $snmpdconf .= <<<EOD
1208
begemotSnmpdCommunityString.0.2 = $(write)
1209

    
1210
EOD;
1211
		}
1212
*/
1213

    
1214

    
1215
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1216
		    $snmpdconf .= <<<EOD
1217
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1218
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1219
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1220

    
1221
EOD;
1222
		}
1223

    
1224

    
1225
		$snmpdconf .= <<<EOD
1226
begemotSnmpdCommunityDisable    = 1
1227

    
1228
EOD;
1229

    
1230
		if(isset($config['snmpd']['bindlan'])) {
1231
			$bind_to_ip = get_interface_ip("lan");
1232
		} else {
1233
			$bind_to_ip = "0.0.0.0";
1234
		}
1235

    
1236
		if(is_port( $config['snmpd']['pollport'] )) {
1237
		    $snmpdconf .= <<<EOD
1238
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1239

    
1240
EOD;
1241

    
1242
		}
1243

    
1244
		$snmpdconf .= <<<EOD
1245
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1246
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1247

    
1248
# These are bsnmp macros not php vars.
1249
sysContact      = $(contact)
1250
sysLocation     = $(location)
1251
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1252

    
1253
snmpEnableAuthenTraps = 2
1254

    
1255
EOD;
1256

    
1257
		if (is_array( $config['snmpd']['modules'] )) {
1258
		    if(isset($config['snmpd']['modules']['mibii'])) {
1259
			$snmpdconf .= <<<EOD
1260
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1261

    
1262
EOD;
1263
		    }
1264

    
1265
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1266
			$snmpdconf .= <<<EOD
1267
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1268
%netgraph
1269
begemotNgControlNodeName = "snmpd"
1270

    
1271
EOD;
1272
		    }
1273

    
1274
		    if(isset($config['snmpd']['modules']['pf'])) {
1275
			$snmpdconf .= <<<EOD
1276
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1277

    
1278
EOD;
1279
		    }
1280

    
1281
		    if(isset($config['snmpd']['modules']['hostres'])) {
1282
			$snmpdconf .= <<<EOD
1283
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1284

    
1285
EOD;
1286
		    }
1287
		    if(isset($config['snmpd']['modules']['bridge'])) {
1288
			$snmpdconf .= <<<EOD
1289
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1290
# config must end with blank line
1291

    
1292

    
1293
EOD;
1294
		    }
1295
		}
1296

    
1297
		fwrite($fd, $snmpdconf);
1298
		fclose($fd);
1299

    
1300
		if (isset($config['snmpd']['bindlan'])) {
1301
			$bindlan = "";
1302
		}
1303

    
1304
		/* run bsnmpd */
1305
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1306
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1307

    
1308
		if ($g['booting'])
1309
			echo gettext("done.") . "\n";
1310
	}
1311

    
1312
	return 0;
1313
}
1314

    
1315
function services_dnsupdate_process($int = "") {
1316
	global $config, $g;
1317
	if(isset($config['system']['developerspew'])) {
1318
		$mt = microtime();
1319
		echo "services_dnsupdate_process() being called $mt\n";
1320
	}
1321

    
1322
	/* Dynamic DNS updating active? */
1323
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1324
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1325
			if (!isset($dnsupdate['enable']))
1326
				continue;
1327
			if (!empty($int) && $int != $dnsupdate['interface'])
1328
				continue;
1329

    
1330
			/* determine interface name */
1331
			$if = get_real_interface($dnsupdate['interface']);
1332
			$wanip = get_interface_ip($dnsupdate['interface']);
1333
			if ($wanip) {
1334

    
1335
				$keyname = $dnsupdate['keyname'];
1336
				/* trailing dot */
1337
				if (substr($keyname, -1) != ".")
1338
					$keyname .= ".";
1339

    
1340
				$hostname = $dnsupdate['host'];
1341
				/* trailing dot */
1342
				if (substr($hostname, -1) != ".")
1343
					$hostname .= ".";
1344

    
1345
				/* write private key file
1346
				   this is dumb - public and private keys are the same for HMAC-MD5,
1347
				   but nsupdate insists on having both */
1348
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1349
				$privkey .= <<<EOD
1350
Private-key-format: v1.2
1351
Algorithm: 157 (HMAC)
1352
Key: {$dnsupdate['keydata']}
1353

    
1354
EOD;
1355
				fwrite($fd, $privkey);
1356
				fclose($fd);
1357

    
1358
				/* write public key file */
1359
				if ($dnsupdate['keytype'] == "zone") {
1360
					$flags = 257;
1361
					$proto = 3;
1362
				} else if ($dnsupdate['keytype'] == "host") {
1363
					$flags = 513;
1364
					$proto = 3;
1365
				} else if ($dnsupdate['keytype'] == "user") {
1366
					$flags = 0;
1367
					$proto = 2;
1368
				}
1369

    
1370
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.key", "w");
1371
				fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n");
1372
				fclose($fd);
1373

    
1374
				/* generate update instructions */
1375
				$upinst = "";
1376
				if (!empty($dnsupdate['server']))
1377
					$upinst .= "server {$dnsupdate['server']}\n";
1378
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1379
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1380
				$upinst .= "\n";	/* mind that trailing newline! */
1381

    
1382
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1383
				fwrite($fd, $upinst);
1384
				fclose($fd);
1385

    
1386
				/* invoke nsupdate */
1387
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1388
				if (isset($dnsupdate['usetcp']))
1389
					$cmd .= " -v";
1390
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1391
	
1392
				mwexec_bg($cmd);
1393
			}
1394
		}
1395
	}
1396

    
1397
	return 0;
1398
}
1399

    
1400
function setup_wireless_olsr() {
1401
	global $config, $g;
1402
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1403
		return;
1404
	if(isset($config['system']['developerspew'])) {
1405
		$mt = microtime();
1406
		echo "setup_wireless_olsr($interface) being called $mt\n";
1407
	}
1408
	conf_mount_rw();
1409
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1410
		$olsr_enable = $olsrd['enable'];
1411
		if($olsr_enable <> "on") {
1412
			if (is_process_running("olsrd"))
1413
				mwexec("/usr/bin/killall olsrd", true);
1414
			return;
1415
		}
1416
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1417

    
1418
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1419
			$enableannounce .= "\nHna4\n";
1420
			$enableannounce .= "{\n";
1421
		if($olsrd['announcedynamicroute'])
1422
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1423
		if($olsrd['enableannounce'] == "on")
1424
			$enableannounce .= "0.0.0.0 0.0.0.0";
1425
			$enableannounce .= "\n}\n";
1426
		} else {
1427
			$enableannounce = "";
1428
		}
1429

    
1430
		$olsr .= <<<EODA
1431
#
1432
# olsr.org OLSR daemon config file
1433
#
1434
# Lines starting with a # are discarded
1435
#
1436
# This file was generated by setup_wireless_olsr() in services.inc
1437
#
1438

    
1439
# This file is an example of a typical
1440
# configuration for a mostly static
1441
# network(regarding mobility) using
1442
# the LQ extention
1443

    
1444
# Debug level(0-9)
1445
# If set to 0 the daemon runs in the background
1446

    
1447
DebugLevel	2
1448

    
1449
# IP version to use (4 or 6)
1450

    
1451
IpVersion	4
1452

    
1453
# Clear the screen each time the internal state changes
1454

    
1455
ClearScreen     yes
1456

    
1457
{$enableannounce}
1458

    
1459
# Should olsrd keep on running even if there are
1460
# no interfaces available? This is a good idea
1461
# for a PCMCIA/USB hotswap environment.
1462
# "yes" OR "no"
1463

    
1464
AllowNoInt	yes
1465

    
1466
# TOS(type of service) value for
1467
# the IP header of control traffic.
1468
# If not set it will default to 16
1469

    
1470
#TosValue	16
1471

    
1472
# The fixed willingness to use(0-7)
1473
# If not set willingness will be calculated
1474
# dynamically based on battery/power status
1475
# if such information is available
1476

    
1477
#Willingness    	4
1478

    
1479
# Allow processes like the GUI front-end
1480
# to connect to the daemon.
1481

    
1482
IpcConnect
1483
{
1484
     # Determines how many simultaneously
1485
     # IPC connections that will be allowed
1486
     # Setting this to 0 disables IPC
1487

    
1488
     MaxConnections  0
1489

    
1490
     # By default only 127.0.0.1 is allowed
1491
     # to connect. Here allowed hosts can
1492
     # be added
1493

    
1494
     Host            127.0.0.1
1495
     #Host            10.0.0.5
1496

    
1497
     # You can also specify entire net-ranges
1498
     # that are allowed to connect. Multiple
1499
     # entries are allowed
1500

    
1501
     #Net             192.168.1.0 255.255.255.0
1502
}
1503

    
1504
# Wether to use hysteresis or not
1505
# Hysteresis adds more robustness to the
1506
# link sensing but delays neighbor registration.
1507
# Used by default. 'yes' or 'no'
1508

    
1509
UseHysteresis	no
1510

    
1511
# Hysteresis parameters
1512
# Do not alter these unless you know
1513
# what you are doing!
1514
# Set to auto by default. Allowed
1515
# values are floating point values
1516
# in the interval 0,1
1517
# THR_LOW must always be lower than
1518
# THR_HIGH.
1519

    
1520
#HystScaling	0.50
1521
#HystThrHigh	0.80
1522
#HystThrLow	0.30
1523

    
1524

    
1525
# Link quality level
1526
# 0 = do not use link quality
1527
# 1 = use link quality for MPR selection
1528
# 2 = use link quality for MPR selection and routing
1529
# Defaults to 0
1530

    
1531
LinkQualityLevel	{$olsrd['enablelqe']}
1532

    
1533
# Link quality window size
1534
# Defaults to 10
1535

    
1536
LinkQualityWinSize	10
1537

    
1538
# Polling rate in seconds(float).
1539
# Default value 0.05 sec
1540

    
1541
Pollrate	0.05
1542

    
1543

    
1544
# TC redundancy
1545
# Specifies how much neighbor info should
1546
# be sent in TC messages
1547
# Possible values are:
1548
# 0 - only send MPR selectors
1549
# 1 - send MPR selectors and MPRs
1550
# 2 - send all neighbors
1551
#
1552
# defaults to 0
1553

    
1554
TcRedundancy	2
1555

    
1556
#
1557
# MPR coverage
1558
# Specifies how many MPRs a node should
1559
# try select to reach every 2 hop neighbor
1560
#
1561
# Can be set to any integer >0
1562
#
1563
# defaults to 1
1564

    
1565
MprCoverage	3
1566

    
1567
# Example plugin entry with parameters:
1568

    
1569
EODA;
1570

    
1571
if($olsrd['enablehttpinfo'] == "on") {
1572
	$olsr .= <<<EODB
1573

    
1574
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1575
{
1576
    PlParam     "port"   "{$olsrd['port']}"
1577
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1578
}
1579

    
1580
EODB;
1581

    
1582
}
1583

    
1584
if($olsrd['enabledsecure'] == "on") {
1585
	$olsr .= <<<EODC
1586

    
1587
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1588
{
1589
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1590
}
1591

    
1592
EODC;
1593

    
1594
}
1595

    
1596
if($olsrd['enabledyngw'] == "on") {
1597

    
1598
	/* unset default route, olsr auto negotiates */
1599
	mwexec("/sbin/route delete default");
1600

    
1601
	$olsr .= <<<EODE
1602

    
1603
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1604
{
1605
    # how often to look for a inet gw, in seconds
1606
    # defaults to 5 secs, if commented out
1607
    PlParam     "Interval"   "{$olsrd['polling']}"
1608

    
1609
    # if one or more IPv4 addresses are given, do a ping on these in
1610
    # descending order to validate that there is not only an entry in
1611
    # routing table, but also a real internet connection. If any of
1612
    # these addresses could be pinged successfully, the test was
1613
    # succesful, i.e. if the ping on the 1st address was successful,the
1614
    # 2nd won't be pinged
1615
    PlParam     "Ping"       "{$olsrd['ping']}"
1616
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1617
}
1618

    
1619
EODE;
1620

    
1621
}
1622

    
1623
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1624
	$interfaces = explode(',', $conf['iface_array']);
1625
	foreach($interfaces as $interface) {
1626
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1627
$olsr .= <<<EODAD
1628
Interface "{$realinterface}"
1629
{
1630

    
1631
    # Hello interval in seconds(float)
1632
    HelloInterval    2.0
1633

    
1634
    # HELLO validity time
1635
    HelloValidityTime	20.0
1636

    
1637
    # TC interval in seconds(float)
1638
    TcInterval        5.0
1639

    
1640
    # TC validity time
1641
    TcValidityTime	30.0
1642

    
1643
    # MID interval in seconds(float)
1644
    MidInterval	5.0
1645

    
1646
    # MID validity time
1647
    MidValidityTime	30.0
1648

    
1649
    # HNA interval in seconds(float)
1650
    HnaInterval	5.0
1651

    
1652
    # HNA validity time
1653
    HnaValidityTime 	30.0
1654

    
1655
    # When multiple links exist between hosts
1656
    # the weight of interface is used to determine
1657
    # the link to use. Normally the weight is
1658
    # automatically calculated by olsrd based
1659
    # on the characteristics of the interface,
1660
    # but here you can specify a fixed value.
1661
    # Olsrd will choose links with the lowest value.
1662

    
1663
    # Weight 0
1664

    
1665

    
1666
}
1667

    
1668
EODAD;
1669

    
1670
	}
1671
	break;
1672
}
1673
		fwrite($fd, $olsr);
1674
		fclose($fd);
1675
	}
1676

    
1677
	if (is_process_running("olsrd"))
1678
		mwexec("/usr/bin/killall olsrd", true);
1679

    
1680
	sleep(2);
1681

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

    
1684
	conf_mount_ro();
1685
}
1686

    
1687
/* configure cron service */
1688
function configure_cron() {
1689
	global $g, $config;
1690

    
1691
	conf_mount_rw();
1692
	/* preserve existing crontab entries */
1693
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1694
	
1695
	for ($i = 0; $i < count($crontab_contents); $i++) {
1696
		$cron_item =& $crontab_contents[$i];
1697
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
1698
			array_splice($crontab_contents, $i - 1);
1699
			break;
1700
		}
1701
	}
1702
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
1703
	
1704
	
1705
	if (is_array($config['cron']['item'])) {
1706
		$crontab_contents .= "#\n";
1707
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
1708
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
1709
		$crontab_contents .= "#\n";
1710

    
1711
		foreach ($config['cron']['item'] as $item) {
1712
			$crontab_contents .= "\n{$item['minute']}\t";
1713
			$crontab_contents .= "{$item['hour']}\t";
1714
			$crontab_contents .= "{$item['mday']}\t";
1715
			$crontab_contents .= "{$item['month']}\t";
1716
			$crontab_contents .= "{$item['wday']}\t";
1717
			$crontab_contents .= "{$item['who']}\t";
1718
			$crontab_contents .= "{$item['command']}";
1719
		}
1720
    
1721
		$crontab_contents .= "\n#\n";
1722
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
1723
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
1724
		$crontab_contents .= "#\n\n";
1725
	}
1726
	
1727
	/* please maintain the newline at the end of file */
1728
	file_put_contents("/etc/crontab", $crontab_contents);
1729

    
1730
	/* do a HUP kill to force sync changes */
1731
	exec('/bin/pkill -HUP cron');
1732

    
1733
	conf_mount_ro();
1734
}
1735

    
1736
function upnp_action ($action) {
1737
	global $g, $config;
1738
	switch($action) {
1739
		case "start":
1740
			if (file_exists('/var/etc/miniupnpd.conf')) {
1741
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
1742
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
1743
			}
1744
			break;
1745
		case "stop":
1746
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
1747
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
1748
				mwexec('killall miniupnpd 2>/dev/null', true);
1749
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1750
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1751
			break;
1752
		case "restart":
1753
			upnp_action('stop');
1754
			upnp_action('start');
1755
			break;
1756
	}
1757
}
1758

    
1759
function upnp_start() {
1760
	global $config;
1761

    
1762
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1763
		return;
1764

    
1765
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1766
		echo gettext("Starting UPnP service... ");
1767
		require_once('/usr/local/pkg/miniupnpd.inc');
1768
		sync_package_miniupnpd();
1769
		echo "done.\n";
1770
	}
1771
}
1772

    
1773
function install_cron_job($command, $active=false, $minute="0", $hour="*", $monthday="*", $month="*", $weekday="*", $who="root") {
1774
	global $config, $g;
1775

    
1776
	$is_installed = false;
1777

    
1778
	if(!$config['cron']['item'])
1779
		return;
1780

    
1781
	$x=0;
1782
	foreach($config['cron']['item'] as $item) {
1783
		if(strstr($item['command'], $command)) {
1784
			$is_installed = true;
1785
			break;
1786
		}
1787
		$x++;
1788
	}
1789

    
1790
	if($active) {
1791
		$cron_item = array();
1792
		$cron_item['minute'] = $minute;
1793
		$cron_item['hour'] = $hour;
1794
		$cron_item['mday'] = $monthday;
1795
		$cron_item['month'] = $month;
1796
		$cron_item['wday'] = $weekday;
1797
		$cron_item['who'] = $who;
1798
		$cron_item['command'] = $command;
1799
		if(!$is_installed) {
1800
			$config['cron']['item'][] = $cron_item;
1801
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
1802
		} else {
1803
			$config['cron']['item'][$x] = $cron_item;
1804
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
1805
		}
1806
	} else {
1807
		if(($is_installed == true) && ($x > 0)) {
1808
			unset($config['cron']['item'][$x]);
1809
			write_config(sprintf(gettext("Remvoed cron job for %s"), $command));
1810
		}
1811
	}
1812
	configure_cron();
1813
}
1814

    
1815
?>
(44-44/61)