Project

General

Profile

Download (49.1 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
		if ($config['dnsmasq']['custom_options']) {
1126
			$args = '';
1127
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1128
				$args .= "--$c ";
1129
		}
1130

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

    
1134
		if ($g['booting'])
1135
			echo gettext("done.") . "\n";
1136
	}
1137

    
1138
	if (!$g['booting']) {
1139
		if(services_dhcpd_configure()!=0)
1140
			$return = 1;
1141
	}
1142

    
1143
	return $return;
1144
}
1145

    
1146
function services_snmpd_configure() {
1147
	global $config, $g;
1148
	if(isset($config['system']['developerspew'])) {
1149
		$mt = microtime();
1150
		echo "services_snmpd_configure() being called $mt\n";
1151
	}
1152

    
1153
	/* kill any running snmpd */
1154
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1155
	sleep(2);
1156
	if(is_process_running("bsnmpd")) 
1157
		mwexec("/usr/bin/killall bsnmpd", true);
1158

    
1159
	if (isset($config['snmpd']['enable'])) {
1160

    
1161
		if ($g['booting'])
1162
			echo gettext("Starting SNMP daemon... ");
1163

    
1164
		/* generate snmpd.conf */
1165
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1166
		if (!$fd) {
1167
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1168
			return 1;
1169
		}
1170

    
1171

    
1172
		$snmpdconf = <<<EOD
1173
location := "{$config['snmpd']['syslocation']}"
1174
contact := "{$config['snmpd']['syscontact']}"
1175
read := "{$config['snmpd']['rocommunity']}"
1176

    
1177
EOD;
1178

    
1179
/* No docs on what write strings do there for disable for now.
1180
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1181
		    $snmpdconf .= <<<EOD
1182
# write string
1183
write := "{$config['snmpd']['rwcommunity']}"
1184

    
1185
EOD;
1186
		}
1187
*/
1188

    
1189

    
1190
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1191
		    $snmpdconf .= <<<EOD
1192
# SNMP Trap support.
1193
traphost := {$config['snmpd']['trapserver']}
1194
trapport := {$config['snmpd']['trapserverport']}
1195
trap := "{$config['snmpd']['trapstring']}"
1196

    
1197

    
1198
EOD;
1199
		}
1200

    
1201

    
1202
		$snmpdconf .= <<<EOD
1203
system := 1     # pfSense
1204
%snmpd
1205
begemotSnmpdDebugDumpPdus       = 2
1206
begemotSnmpdDebugSyslogPri      = 7
1207
begemotSnmpdCommunityString.0.1 = $(read)
1208

    
1209
EOD;
1210

    
1211
/* No docs on what write strings do there for disable for now.
1212
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1213
		    $snmpdconf .= <<<EOD
1214
begemotSnmpdCommunityString.0.2 = $(write)
1215

    
1216
EOD;
1217
		}
1218
*/
1219

    
1220

    
1221
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1222
		    $snmpdconf .= <<<EOD
1223
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1224
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1225
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1226

    
1227
EOD;
1228
		}
1229

    
1230

    
1231
		$snmpdconf .= <<<EOD
1232
begemotSnmpdCommunityDisable    = 1
1233

    
1234
EOD;
1235

    
1236
		if(isset($config['snmpd']['bindlan'])) {
1237
			$bind_to_ip = get_interface_ip("lan");
1238
		} else {
1239
			$bind_to_ip = "0.0.0.0";
1240
		}
1241

    
1242
		if(is_port( $config['snmpd']['pollport'] )) {
1243
		    $snmpdconf .= <<<EOD
1244
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1245

    
1246
EOD;
1247

    
1248
		}
1249

    
1250
		$snmpdconf .= <<<EOD
1251
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1252
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1253

    
1254
# These are bsnmp macros not php vars.
1255
sysContact      = $(contact)
1256
sysLocation     = $(location)
1257
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1258

    
1259
snmpEnableAuthenTraps = 2
1260

    
1261
EOD;
1262

    
1263
		if (is_array( $config['snmpd']['modules'] )) {
1264
		    if(isset($config['snmpd']['modules']['mibii'])) {
1265
			$snmpdconf .= <<<EOD
1266
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1267

    
1268
EOD;
1269
		    }
1270

    
1271
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1272
			$snmpdconf .= <<<EOD
1273
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1274
%netgraph
1275
begemotNgControlNodeName = "snmpd"
1276

    
1277
EOD;
1278
		    }
1279

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

    
1284
EOD;
1285
		    }
1286

    
1287
		    if(isset($config['snmpd']['modules']['hostres'])) {
1288
			$snmpdconf .= <<<EOD
1289
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1290

    
1291
EOD;
1292
		    }
1293
		    if(isset($config['snmpd']['modules']['bridge'])) {
1294
			$snmpdconf .= <<<EOD
1295
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1296
# config must end with blank line
1297

    
1298

    
1299
EOD;
1300
		    }
1301
		}
1302

    
1303
		fwrite($fd, $snmpdconf);
1304
		fclose($fd);
1305

    
1306
		if (isset($config['snmpd']['bindlan'])) {
1307
			$bindlan = "";
1308
		}
1309

    
1310
		/* run bsnmpd */
1311
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1312
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1313

    
1314
		if ($g['booting'])
1315
			echo gettext("done.") . "\n";
1316
	}
1317

    
1318
	return 0;
1319
}
1320

    
1321
function services_dnsupdate_process($int = "") {
1322
	global $config, $g;
1323
	if(isset($config['system']['developerspew'])) {
1324
		$mt = microtime();
1325
		echo "services_dnsupdate_process() being called $mt\n";
1326
	}
1327

    
1328
	/* Dynamic DNS updating active? */
1329
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1330
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1331
			if (!isset($dnsupdate['enable']))
1332
				continue;
1333
			if (!empty($int) && $int != $dnsupdate['interface'])
1334
				continue;
1335

    
1336
			/* determine interface name */
1337
			$if = get_real_interface($dnsupdate['interface']);
1338
			$wanip = get_interface_ip($dnsupdate['interface']);
1339
			if ($wanip) {
1340

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

    
1346
				$hostname = $dnsupdate['host'];
1347
				/* trailing dot */
1348
				if (substr($hostname, -1) != ".")
1349
					$hostname .= ".";
1350

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

    
1360
EOD;
1361
				fwrite($fd, $privkey);
1362
				fclose($fd);
1363

    
1364
				/* write public key file */
1365
				if ($dnsupdate['keytype'] == "zone") {
1366
					$flags = 257;
1367
					$proto = 3;
1368
				} else if ($dnsupdate['keytype'] == "host") {
1369
					$flags = 513;
1370
					$proto = 3;
1371
				} else if ($dnsupdate['keytype'] == "user") {
1372
					$flags = 0;
1373
					$proto = 2;
1374
				}
1375

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

    
1380
				/* generate update instructions */
1381
				$upinst = "";
1382
				if (!empty($dnsupdate['server']))
1383
					$upinst .= "server {$dnsupdate['server']}\n";
1384
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1385
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1386
				$upinst .= "\n";	/* mind that trailing newline! */
1387

    
1388
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1389
				fwrite($fd, $upinst);
1390
				fclose($fd);
1391

    
1392
				/* invoke nsupdate */
1393
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1394
				if (isset($dnsupdate['usetcp']))
1395
					$cmd .= " -v";
1396
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1397
	
1398
				mwexec_bg($cmd);
1399
			}
1400
		}
1401
	}
1402

    
1403
	return 0;
1404
}
1405

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

    
1424
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1425
			$enableannounce .= "\nHna4\n";
1426
			$enableannounce .= "{\n";
1427
		if($olsrd['announcedynamicroute'])
1428
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1429
		if($olsrd['enableannounce'] == "on")
1430
			$enableannounce .= "0.0.0.0 0.0.0.0";
1431
			$enableannounce .= "\n}\n";
1432
		} else {
1433
			$enableannounce = "";
1434
		}
1435

    
1436
		$olsr .= <<<EODA
1437
#
1438
# olsr.org OLSR daemon config file
1439
#
1440
# Lines starting with a # are discarded
1441
#
1442
# This file was generated by setup_wireless_olsr() in services.inc
1443
#
1444

    
1445
# This file is an example of a typical
1446
# configuration for a mostly static
1447
# network(regarding mobility) using
1448
# the LQ extention
1449

    
1450
# Debug level(0-9)
1451
# If set to 0 the daemon runs in the background
1452

    
1453
DebugLevel	2
1454

    
1455
# IP version to use (4 or 6)
1456

    
1457
IpVersion	4
1458

    
1459
# Clear the screen each time the internal state changes
1460

    
1461
ClearScreen     yes
1462

    
1463
{$enableannounce}
1464

    
1465
# Should olsrd keep on running even if there are
1466
# no interfaces available? This is a good idea
1467
# for a PCMCIA/USB hotswap environment.
1468
# "yes" OR "no"
1469

    
1470
AllowNoInt	yes
1471

    
1472
# TOS(type of service) value for
1473
# the IP header of control traffic.
1474
# If not set it will default to 16
1475

    
1476
#TosValue	16
1477

    
1478
# The fixed willingness to use(0-7)
1479
# If not set willingness will be calculated
1480
# dynamically based on battery/power status
1481
# if such information is available
1482

    
1483
#Willingness    	4
1484

    
1485
# Allow processes like the GUI front-end
1486
# to connect to the daemon.
1487

    
1488
IpcConnect
1489
{
1490
     # Determines how many simultaneously
1491
     # IPC connections that will be allowed
1492
     # Setting this to 0 disables IPC
1493

    
1494
     MaxConnections  0
1495

    
1496
     # By default only 127.0.0.1 is allowed
1497
     # to connect. Here allowed hosts can
1498
     # be added
1499

    
1500
     Host            127.0.0.1
1501
     #Host            10.0.0.5
1502

    
1503
     # You can also specify entire net-ranges
1504
     # that are allowed to connect. Multiple
1505
     # entries are allowed
1506

    
1507
     #Net             192.168.1.0 255.255.255.0
1508
}
1509

    
1510
# Wether to use hysteresis or not
1511
# Hysteresis adds more robustness to the
1512
# link sensing but delays neighbor registration.
1513
# Used by default. 'yes' or 'no'
1514

    
1515
UseHysteresis	no
1516

    
1517
# Hysteresis parameters
1518
# Do not alter these unless you know
1519
# what you are doing!
1520
# Set to auto by default. Allowed
1521
# values are floating point values
1522
# in the interval 0,1
1523
# THR_LOW must always be lower than
1524
# THR_HIGH.
1525

    
1526
#HystScaling	0.50
1527
#HystThrHigh	0.80
1528
#HystThrLow	0.30
1529

    
1530

    
1531
# Link quality level
1532
# 0 = do not use link quality
1533
# 1 = use link quality for MPR selection
1534
# 2 = use link quality for MPR selection and routing
1535
# Defaults to 0
1536

    
1537
LinkQualityLevel	{$olsrd['enablelqe']}
1538

    
1539
# Link quality window size
1540
# Defaults to 10
1541

    
1542
LinkQualityWinSize	10
1543

    
1544
# Polling rate in seconds(float).
1545
# Default value 0.05 sec
1546

    
1547
Pollrate	0.05
1548

    
1549

    
1550
# TC redundancy
1551
# Specifies how much neighbor info should
1552
# be sent in TC messages
1553
# Possible values are:
1554
# 0 - only send MPR selectors
1555
# 1 - send MPR selectors and MPRs
1556
# 2 - send all neighbors
1557
#
1558
# defaults to 0
1559

    
1560
TcRedundancy	2
1561

    
1562
#
1563
# MPR coverage
1564
# Specifies how many MPRs a node should
1565
# try select to reach every 2 hop neighbor
1566
#
1567
# Can be set to any integer >0
1568
#
1569
# defaults to 1
1570

    
1571
MprCoverage	3
1572

    
1573
# Example plugin entry with parameters:
1574

    
1575
EODA;
1576

    
1577
if($olsrd['enablehttpinfo'] == "on") {
1578
	$olsr .= <<<EODB
1579

    
1580
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1581
{
1582
    PlParam     "port"   "{$olsrd['port']}"
1583
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1584
}
1585

    
1586
EODB;
1587

    
1588
}
1589

    
1590
if($olsrd['enabledsecure'] == "on") {
1591
	$olsr .= <<<EODC
1592

    
1593
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1594
{
1595
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1596
}
1597

    
1598
EODC;
1599

    
1600
}
1601

    
1602
if($olsrd['enabledyngw'] == "on") {
1603

    
1604
	/* unset default route, olsr auto negotiates */
1605
	mwexec("/sbin/route delete default");
1606

    
1607
	$olsr .= <<<EODE
1608

    
1609
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1610
{
1611
    # how often to look for a inet gw, in seconds
1612
    # defaults to 5 secs, if commented out
1613
    PlParam     "Interval"   "{$olsrd['polling']}"
1614

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

    
1625
EODE;
1626

    
1627
}
1628

    
1629
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1630
	$interfaces = explode(',', $conf['iface_array']);
1631
	foreach($interfaces as $interface) {
1632
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1633
$olsr .= <<<EODAD
1634
Interface "{$realinterface}"
1635
{
1636

    
1637
    # Hello interval in seconds(float)
1638
    HelloInterval    2.0
1639

    
1640
    # HELLO validity time
1641
    HelloValidityTime	20.0
1642

    
1643
    # TC interval in seconds(float)
1644
    TcInterval        5.0
1645

    
1646
    # TC validity time
1647
    TcValidityTime	30.0
1648

    
1649
    # MID interval in seconds(float)
1650
    MidInterval	5.0
1651

    
1652
    # MID validity time
1653
    MidValidityTime	30.0
1654

    
1655
    # HNA interval in seconds(float)
1656
    HnaInterval	5.0
1657

    
1658
    # HNA validity time
1659
    HnaValidityTime 	30.0
1660

    
1661
    # When multiple links exist between hosts
1662
    # the weight of interface is used to determine
1663
    # the link to use. Normally the weight is
1664
    # automatically calculated by olsrd based
1665
    # on the characteristics of the interface,
1666
    # but here you can specify a fixed value.
1667
    # Olsrd will choose links with the lowest value.
1668

    
1669
    # Weight 0
1670

    
1671

    
1672
}
1673

    
1674
EODAD;
1675

    
1676
	}
1677
	break;
1678
}
1679
		fwrite($fd, $olsr);
1680
		fclose($fd);
1681
	}
1682

    
1683
	if (is_process_running("olsrd"))
1684
		mwexec("/usr/bin/killall olsrd", true);
1685

    
1686
	sleep(2);
1687

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

    
1690
	conf_mount_ro();
1691
}
1692

    
1693
/* configure cron service */
1694
function configure_cron() {
1695
	global $g, $config;
1696

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

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

    
1736
	/* do a HUP kill to force sync changes */
1737
	exec('/bin/pkill -HUP cron');
1738

    
1739
	conf_mount_ro();
1740
}
1741

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

    
1765
function upnp_start() {
1766
	global $config;
1767

    
1768
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1769
		return;
1770

    
1771
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1772
		echo gettext("Starting UPnP service... ");
1773
		require_once('/usr/local/pkg/miniupnpd.inc');
1774
		sync_package_miniupnpd();
1775
		echo "done.\n";
1776
	}
1777
}
1778

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

    
1782
	$is_installed = false;
1783

    
1784
	if(!$config['cron']['item'])
1785
		return;
1786

    
1787
	$x=0;
1788
	foreach($config['cron']['item'] as $item) {
1789
		if(strstr($item['command'], $command)) {
1790
			$is_installed = true;
1791
			break;
1792
		}
1793
		$x++;
1794
	}
1795

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

    
1821
?>
(44-44/61)