Project

General

Profile

Download (49.4 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 ($g['platform'] == 'jail') 
47
		return;
48

    
49
	if(isset($config['system']['developerspew'])) {
50
		$mt = microtime();
51
		echo "services_rtadvd_configure() being called $mt\n";
52
	}
53

    
54
	if(is_process_running("rtadvd")) {
55
		mwexec("killall -9 rtadvd", true);
56
	}
57

    
58
	if (!is_array($config['dhcpdv6']))
59
		$config['dhcpdv6'] = array();
60

    
61
	$dhcpdv6cfg = $config['dhcpdv6'];
62
	$Iflist = get_configured_interface_list();
63

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

    
71
	/* raflags, other o, managed=64 m, stateful=128, both=192 */
72
	/* pinfoflags 0 = disable slaac */
73

    
74
	$rtadvdconf = "# Automatically Generated, do not edit\n";
75
	$rtadvdconf = <<<EOD
76

    
77
#
78
# common definitions.
79
#
80
default:\
81
        :raflags#0:rltime#3600:\
82
        :vltime#360000:pltime#360000:mtu#1500:
83
ether:\
84
        :mtu#1280:tc=default:
85

    
86
EOD;
87

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

    
94
		$realif = get_real_interface($dhcpv6if);
95
		$rtadvdifs[] = $realif;
96

    
97
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
98
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
99
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
100
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
101

    
102
		$rtadvdconf .= "# Generated for DHCPv6 Server $dhcpv6if\n";
103
		$rtadvdconf .= "{$realif}:\\\n";
104
		$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
105
		$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
106
		switch($dhcpv6ifconf['mode']) {
107
			case "managed":
108
				$rtadvdconf .= "\t:raflags=\"m\":\\\n";
109
				$rtadvdconf .= "\t:pinfoflags=\"\":\\\n";
110
				break;
111
			case "router":
112
				$rtadvdconf .= "\t:pinfoflags=\"\":\\\n";
113
				break;
114
			case "assist":
115
				$rtadvdconf .= "\t:raflags=\"mo\":\\\n";
116
				break;
117
			default:
118
				$rtadvdconf .= "\t:raflags#0:\\\n";
119
				break;				
120

    
121
		}
122
		$rtadvdconf .= "\t:tc=ether:\n";
123
		$rtadvdconf .= "\n\n";
124
		$rtadvdnum++;
125
	}
126

    
127
	foreach ($Iflist as $if => $ifdescr) {
128
		if(!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id']))
129
			continue;
130

    
131
		$realif = get_real_interface($if);
132
		$rtadvdifs[] = $realif;
133

    
134
		$ifcfgipv6 = get_interface_ipv6($if);
135
		$ifcfgsnv6 = get_interface_subnetv6($if);
136
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
137
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
138

    
139
		if(is_ipaddrv6($subnetv6)) {
140
			$rtadvdconf .= "# Generated for DHCP-PD delegation $if\n";
141
			$rtadvdconf .= "{$realif}:\\\n";
142
			$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
143
			$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
144
			$rtadvdconf .= "\t:raflags=\"mo\":\\\n";
145
			$rtadvdconf .= "\t:tc=ether:\n";
146
			$rtadvdconf .= "\n\n"; 
147
			$rtadvdnum++;
148
		}
149
	}
150

    
151
	fwrite($fd, $rtadvdconf);
152
	fclose($fd);
153

    
154
	if(count($rtadvdifs) > 0) {
155
		mwexec("/usr/sbin/rtadvd -c {$g['varetc_path']}/rtadvd.conf " . join(" ", $rtadvdifs));
156
	}
157
	return 0;
158
}
159

    
160
function services_dhcpd_configure() {
161
	global $config, $g;
162

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

    
184
	services_dhcpdv4_configure();
185
	services_dhcpdv6_configure();
186
	services_rtadvd_configure();
187
	return;
188

    
189
}
190
function services_dhcpdv4_configure() {
191
	global $config, $g;
192
	
193
	if($g['services_dhcp_server_enable'] == false) 
194
		return;
195

    
196
	if(isset($config['system']['developerspew'])) {
197
		$mt = microtime();
198
		echo "services_dhcpdv4_configure($if) being called $mt\n";
199
	}
200
	
201
	/* kill any running dhcpd */
202
	if(is_process_running("dhcpd")) {
203
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
204
	}
205

    
206
	/* DHCP enabled on any interfaces? */
207
	if (!is_dhcp_server_enabled())
208
		return 0;
209

    
210
	/* if OLSRD is enabled, allow WAN to house DHCP. */
211
	if($config['installedpackages']['olsrd'])
212
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
213
				if($olsrd['enable'])
214
					$is_olsr_enabled = true;
215

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

    
231
	$syscfg = $config['system'];
232
	if (!is_array($config['dhcpd']))
233
		$config['dhcpd'] = array();
234
	$dhcpdcfg = $config['dhcpd'];
235
	$Iflist = get_configured_interface_list();
236
		
237
	if ($g['booting'])
238
		echo gettext("Starting DHCP service...");
239
	else
240
		sleep(1);
241

    
242
	/* write dhcpd.conf */
243
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
244
	if (!$fd) {
245
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
246
		return 1;
247
	}
248

    
249
	$custoptions = "";
250
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
251
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
252
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
253
				if(!empty($item['type']))
254
					$itemtype = $item['type'];
255
				else
256
					$itemtype = "text";
257
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
258
			}
259
		}
260
	}
261

    
262
	$dhcpdconf = <<<EOD
263
	
264
option domain-name "{$syscfg['domain']}";
265
option ldap-server code 95 = text;
266
option domain-search-list code 119 = text;
267
{$custoptions}
268
default-lease-time 7200;
269
max-lease-time 86400;
270
log-facility local7;
271
ddns-update-style none;
272
one-lease-per-client true;
273
deny duplicates;
274
ping-check true;
275

    
276
EOD;
277

    
278
	if(!isset($dhcpifconf['disableauthoritative']))
279
		$dhcpdconf .= "authoritative;\n";
280

    
281
	if(isset($dhcpifconf['alwaysbroadcast'])) 
282
		$dhcpdconf .= "always-broadcast on\n";
283

    
284
	$dhcpdifs = array();
285

    
286
	/*    loop through and determine if we need to setup
287
	 *    failover peer "bleh" entries
288
	 */
289
	$dhcpnum = 0;
290
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
291

    
292
		interfaces_staticarp_configure($dhcpif);
293

    
294
		if (!isset($dhcpifconf['enable']))
295
			continue;
296

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

    
343
EOPP;
344
		$dhcpnum++;
345
		}
346
	}
347

    
348
	$dhcpnum = 0;
349

    
350
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
351

    
352
		$ifcfg = $config['interfaces'][$dhcpif];
353

    
354
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
355
			continue;
356
		$ifcfgip = get_interface_ip($dhcpif);
357
		$ifcfgsn = get_interface_subnet($dhcpif);
358
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
359
		$subnetmask = gen_subnet_mask($ifcfgsn);
360

    
361
		if (!is_ipaddr($subnet))
362
			continue;
363

    
364
		if($is_olsr_enabled == true)
365
			if($dhcpifconf['netmask'])
366
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
367

    
368
		$dnscfg = "";
369

    
370
		if ($dhcpifconf['domain']) {
371
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
372
		}
373
		
374
    		if($dhcpifconf['domainsearchlist'] <> "") {
375
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
376
    		}
377

    
378
		if (isset($dhcpifconf['ddnsupdate'])) {
379
			if($dhcpifconf['ddnsdomain'] <> "") {
380
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
381
			}
382
			$dnscfg .= "	ddns-update-style interim;\n";
383
		}
384

    
385
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
386
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
387
		} else if (isset($config['dnsmasq']['enable'])) {
388
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
389
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
390
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
391
		}
392

    
393
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
394
		$dhcpdconf .= "	pool {\n";
395

    
396
		/* is failover dns setup? */
397
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
398
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
399
			if($dhcpifconf['dnsserver'][1] <> "")
400
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
401
			$dhcpdconf .= ";\n";
402
		}
403

    
404
		if($dhcpifconf['failover_peerip'] <> "")
405
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
406

    
407
		if (isset($dhcpifconf['denyunknown']))
408
		   $dhcpdconf .= "		deny unknown-clients;\n";
409

    
410
		if ($dhcpifconf['gateway'])
411
			$routers = $dhcpifconf['gateway'];
412
		else
413
			$routers = $ifcfgip;
414

    
415
		if($dhcpifconf['failover_peerip'] <> "") {
416
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
417
			$dhcpnum++;
418
		}
419

    
420
		$dhcpdconf .= <<<EOD
421
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
422
	}
423
	option routers {$routers};
424
$dnscfg
425

    
426
EOD;
427
    		// default-lease-time
428
		if ($dhcpifconf['defaultleasetime'])
429
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
430

    
431
		// max-lease-time
432
		if ($dhcpifconf['maxleasetime'])
433
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
434

    
435
		// netbios-name*
436
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
437
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
438
			$dhcpdconf .= "	option netbios-node-type 8;\n";
439
		}
440

    
441
		// ntp-servers
442
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
443
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
444

    
445
		// tftp-server-name
446
		if ($dhcpifconf['tftp'] <> "")
447
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
448

    
449
		// Handle option, number rowhelper values
450
		$dhcpdconf .= "\n";
451
		if($dhcpifconf['numberoptions']['item']) {
452
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
453
				if(empty($item['type']) || $item['type'] == "text")
454
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
455
				else
456
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
457
			}
458
		}
459

    
460
		// ldap-server
461
		if ($dhcpifconf['ldap'] <> "")
462
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
463

    
464
		// net boot information
465
		if(isset($dhcpifconf['netboot'])) {
466
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
467
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
468
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
469
			}
470
			if ($dhcpifconf['rootpath'] <> "") {
471
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
472
      		}
473
		}
474
		
475
		$dhcpdconf .= <<<EOD
476
}
477

    
478
EOD;
479

    
480
		/* add static mappings */
481
		if (is_array($dhcpifconf['staticmap'])) {
482

    
483
			$i = 0;
484
			foreach ($dhcpifconf['staticmap'] as $sm) {
485
				$dhcpdconf .= <<<EOD
486
host s_{$dhcpif}_{$i} {
487
	hardware ethernet {$sm['mac']};
488

    
489
EOD;
490
				if ($sm['ipaddr'])
491
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
492

    
493
				if ($sm['hostname']) {
494
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
495
					$dhhostname = str_replace(".", "_", $dhhostname);
496
					$dhcpdconf .= "	option host-name {$dhhostname};\n";
497
				}
498
				if ($sm['netbootfile'])
499
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
500

    
501
				$dhcpdconf .= "}\n";
502
				$i++;
503
			}
504
		}
505

    
506
		$dhcpdifs[] = get_real_interface($dhcpif);
507
	}
508

    
509
	fwrite($fd, $dhcpdconf);
510
	fclose($fd);
511

    
512
	/* create an empty leases database */
513
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
514
	
515

    
516
	/* fire up dhcpd in a chroot */
517
	if(count($dhcpdifs) > 0) {
518
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
519
			join(" ", $dhcpdifs));
520
	}
521

    
522
	if ($g['booting']) {
523
		print "done.\n";
524
	}
525

    
526
	return 0;
527
}
528

    
529
function services_dhcpdv6_configure() {
530
	global $config, $g;
531
	
532
	if($g['services_dhcp_server_enable'] == false) 
533
		return;
534

    
535
	if(isset($config['system']['developerspew'])) {
536
		$mt = microtime();
537
		echo "services_dhcpd_configure($if) being called $mt\n";
538
	}
539
	
540
	/* kill any running dhcpd */
541
	if(is_process_running("dhcpd")) {
542
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
543
	}
544

    
545
	/* DHCP enabled on any interfaces? */
546
	if (!is_dhcp_server_enabled())
547
		return 0;
548

    
549
	/* if OLSRD is enabled, allow WAN to house DHCP. */
550
	if($config['installedpackages']['olsrd'])
551
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
552
				if($olsrd['enable'])
553
					$is_olsr_enabled = true;
554

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

    
570
	$syscfg = $config['system'];
571
	if (!is_array($config['dhcpdv6']))
572
		$config['dhcpdv6'] = array();
573
	$dhcpdv6cfg = $config['dhcpdv6'];
574
	$Iflist = get_configured_interface_list();
575
		
576
	if ($g['booting'])
577
		echo "Starting DHCPv6 service...";
578
	else
579
		sleep(1);
580

    
581
	/* write dhcpdv6.conf */
582
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
583
	if (! $fdv6) {
584
		printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n");
585
		return 1;
586
	}
587

    
588
	$custoptionsv6 = "";
589
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {	
590
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
591
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
592
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
593
			}
594
		}
595
	}
596

    
597
	$dhcpdv6conf = <<<EOD
598
	
599
option domain-name "{$syscfg['domain']}";
600
option ldap-server code 95 = text;
601
option domain-search-list code 119 = text;
602
{$custoptions}
603
default-lease-time 7200;
604
max-lease-time 86400;
605
log-facility local7;
606
ddns-update-style none;
607
one-lease-per-client true;
608
deny duplicates;
609
ping-check true;
610

    
611
EOD;
612

    
613
	if(!isset($dhcpv6ifconf['disableauthoritative']))
614
		$dhcpdv6conf .= "authoritative;\n";
615

    
616
	if(isset($dhcpv6ifconf['alwaysbroadcast'])) 
617
		$dhcpdv6conf .= "always-broadcast on\n";
618

    
619
	$dhcpdv6ifs = array();
620

    
621
	/*    loop through and determine if we need to setup
622
	 *    failover peer "bleh" entries
623
	 */
624
	$dhcpv6num = 0;
625
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
626

    
627
		if (!isset($dhcpv6ifconf['enable']))
628
			continue;
629

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

    
676
EOPP;
677
		$dhcpv6num++;
678
		}
679
	}
680

    
681
	$dhcpv6num = 0;
682
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
683

    
684
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
685

    
686
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
687
			continue;
688
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
689
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
690
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
691
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
692

    
693
		if($is_olsr_enabled == true)
694
			if($dhcpv6ifconf['netmask'])
695
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
696

    
697
		$dnscfgv6 = "";
698

    
699
		if ($dhcpv6ifconf['domain']) {
700
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
701
		}
702
		
703
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
704
			$dnscfgv6 .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
705
    		}
706

    
707
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
708
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
709
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
710
			}
711
			$dnscfgv6 .= "	ddns-update-style interim;\n";
712
		}
713

    
714
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
715
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
716
		} else if (isset($config['dnsmasq']['enable'])) {
717
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
718
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
719
			$dns_arrv6 = array();
720
			foreach($syscfg['dnsserver'] as $dnsserver) {
721
				if(is_ipaddrv6($dnsserver)) {
722
					$dns_arrv6[] = $dnsserver;
723
				}
724
			}
725
			if(!empty($dns_arrv6))
726
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
727
		}
728

    
729
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
730
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
731

    
732
		/* is failover dns setup? */
733
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
734
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
735
			if($dhcpv6ifconf['dnsserver'][1] <> "")
736
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
737
			$dhcpdv6conf .= ";\n";
738
		}
739

    
740
		if($dhcpv6ifconf['failover_peerip'] <> "")
741
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
742

    
743
		if (isset($dhcpv6ifconf['denyunknown']))
744
		   $dhcpdv6conf .= "		deny unknown clients;\n";
745

    
746
		if ($dhcpv6ifconf['gateway'])
747
			$routersv6 = $dhcpv6ifconf['gateway'];
748
		else
749
			$routersv6 = $ifcfgipv6;
750

    
751
		if($dhcpv6ifconf['failover_peerip'] <> "") {
752
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
753
			$dhcpv6num++;
754
		}
755

    
756
		$dhcpdv6conf .= <<<EOD
757
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
758
	# Not supported in IPv6; option dhcp6.routers {$routersv6};
759
$dnscfgv6
760

    
761
EOD;
762

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

    
766
		}
767
    		// default-lease-time
768
		if ($dhcpv6ifconf['defaultleasetime'])
769
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
770

    
771
		// max-lease-time
772
		if ($dhcpv6ifconf['maxleasetime'])
773
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
774

    
775
		// ntp-servers
776
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0])
777
			$dhcpdv6conf .= "	option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
778

    
779
		// tftp-server-name
780
		if ($dhcpv6ifconf['tftp'] <> "")
781
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
782

    
783
		// Handle option, number rowhelper values
784
		$dhcpdv6conf .= "\n";
785
		if($dhcpv6ifconf['numberoptions']['item']) {
786
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
787
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
788
			}
789
		}
790

    
791
		// ldap-server
792
		if ($dhcpv6ifconf['ldap'] <> "")
793
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
794

    
795
		// net boot information
796
		if(isset($dhcpv6ifconf['netboot'])) {
797
			if (($dhcpv6ifconf['next-server'] <> "") && ($dhcpv6ifconf['filename'] <> "")) {
798
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['next-server']};\n";
799
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
800
			}
801
			if ($dhcpv6ifconf['rootpath'] <> "") {
802
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
803
      		}
804
	}
805
		
806
		$dhcpdv6conf .= <<<EOD
807
}
808
EOD;
809

    
810
		/* add static mappings */
811
		/* Needs to use DUID */
812
		if (is_array($dhcpv6ifconf['staticmap'])) {
813

    
814
			$i = 0;
815
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
816
				$dhcpdv6conf .= <<<EOD
817
host s_{$dhcpv6if}_{$i} {
818
	host-identifier option dhcp6.client-id {$sm['duid']};
819

    
820
EOD;
821
				if ($sm['ipaddrv6'])
822
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
823

    
824
				if ($sm['hostname']) {
825
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
826
					$dhhostname = str_replace(".", "_", $dhhostname);
827
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
828
				}
829
				if ($sm['netbootfile'])
830
					$dhcpdv6conf .= "	filename \"{$sm['netbootfile']}\";\n";
831

    
832
				$dhcpdv6conf .= "}\n";
833
				$i++;
834
			}
835
		}
836
		
837
		if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") {
838
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
839
			$dhcpdv6ifs[] = $realif;
840
			exec("/sbin/ifconfig {$realif} |awk  '/ether/ {print $2}'", $mac);
841
			$v6address = generate_ipv6_from_mac($mac[0]);
842
			/* Create link local address for bridges */
843
			if(stristr("$realif", "bridge")) {
844
				mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
845
			}
846
		}
847
	}
848

    
849
	fwrite($fdv6, $dhcpdv6conf);
850
	fclose($fdv6);
851
	/* create an empty leases v6 database */
852
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
853
	
854

    
855
	/* fire up dhcpd in a chroot */
856
	if(count($dhcpdv6ifs) > 0) {
857
		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 " .
858
			join(" ", $dhcpdv6ifs));
859
	}
860

    
861
	if ($g['booting']) {
862
		print gettext("done.") . "\n";
863
	}
864

    
865
	return 0;
866
}
867

    
868
function services_igmpproxy_configure() {
869
        global $config, $g;
870

    
871
        /* kill any running igmpproxy */
872
        killbyname("igmpproxy");
873

    
874
	if (!is_array($config['igmpproxy']['igmpentry']))
875
		return 1;
876

    
877
        $iflist = get_configured_interface_list();
878

    
879
        $igmpconf = <<<EOD
880

    
881
##------------------------------------------------------
882
## Enable Quickleave mode (Sends Leave instantly)
883
##------------------------------------------------------
884
quickleave
885

    
886
EOD;
887

    
888
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
889
                unset($iflist[$igmpcf['ifname']]);
890
                $realif = get_real_interface($igmpcf['ifname']);
891
                if (empty($igmpcf['threshold']))
892
                        $threshld = 1;
893
                else
894
                        $threshld = $igmpcf['threshold'];
895
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
896

    
897
                if ($igmpcf['address'] <> "") {
898
                        $item = explode(" ", $igmpcf['address']);
899
                        foreach($item as $iww)
900
                                $igmpconf .= "altnet {$iww}\n";
901
                }
902
                $igmpconf .= "\n";
903
        }
904
        foreach ($iflist as $ifn) {
905
                $realif = get_real_interface($ifn);
906
                $igmpconf .= "phyint {$realif} disabled\n";
907
        }
908
	$igmpconf .= "\n";
909

    
910
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
911
        if (!$igmpfl) {
912
                log_error(gettext("Could not write Igmpproxy configuration file!"));
913
                return;
914
        }
915
        fwrite($igmpfl, $igmpconf);
916
        fclose($igmpfl);
917

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

    
921
        return 0;
922
}
923

    
924
function services_dhcrelay_configure() {
925
	global $config, $g;
926
	if ($g['platform'] == 'jail')
927
		return;
928
	if(isset($config['system']['developerspew'])) {
929
		$mt = microtime();
930
		echo "services_dhcrelay_configure() being called $mt\n";
931
	}
932

    
933
	/* kill any running dhcrelay */
934
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
935

    
936
	$dhcrelaycfg =& $config['dhcrelay'];
937

    
938
	/* DHCPRelay enabled on any interfaces? */
939
	if (!isset($dhcrelaycfg['enable']))
940
		return 0;
941

    
942
	if ($g['booting'])
943
		echo gettext("Starting DHCP relay service...");
944
	else
945
		sleep(1);
946

    
947
	$iflist = get_configured_interface_list();
948

    
949
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
950
	foreach ($dhcifaces as $dhcrelayif) {
951
		if (!isset($iflist[$dhcrelayif]) ||
952
			link_interface_to_bridge($dhcrelayif))
953
			continue;
954

    
955
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
956
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
957
	}
958

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

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

    
1018
		if (!empty($destif))
1019
			$dhcrelayifs[] = $destif;
1020
	}
1021
	$dhcrelayifs = array_unique($dhcrelayifs);
1022

    
1023
	/* fire up dhcrelay */
1024
	if (empty($dhcrelayifs)) {
1025
		log_error("No suitable interface found for running dhcrelay!");
1026
		return; /* XXX */
1027
	}
1028

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

    
1031
	if (isset($dhcrelaycfg['agentoption']))
1032
		$cmd .=  " -a -m replace";
1033

    
1034
	$cmd .= " " . implode(" ", $srvips);
1035
	mwexec($cmd);
1036

    
1037
	return 0;
1038
}
1039

    
1040
function services_dyndns_configure_client($conf) {
1041

    
1042
	if (!isset($conf['enable']))
1043
		return;
1044

    
1045
	/* load up the dyndns.class */
1046
	require_once("dyndns.class");
1047

    
1048
	$dns = new updatedns($dnsService = $conf['type'],
1049
		$dnsHost = $conf['host'],
1050
		$dnsUser = $conf['username'],
1051
		$dnsPass = $conf['password'],
1052
		$dnsWilcard = $conf['wildcard'],
1053
		$dnsMX = $conf['mx'], 
1054
		$dnsIf = "{$conf['interface']}");
1055

    
1056
}
1057

    
1058
function services_dyndns_configure($int = "") {
1059
	global $config, $g;
1060
	if(isset($config['system']['developerspew'])) {
1061
		$mt = microtime();
1062
		echo "services_dyndns_configure() being called $mt\n";
1063
	}
1064

    
1065
	$dyndnscfg = $config['dyndnses']['dyndns'];
1066

    
1067
	if (is_array($dyndnscfg)) {
1068
		if ($g['booting']) 
1069
			echo gettext("Starting DynDNS clients...");
1070

    
1071
		foreach ($dyndnscfg as $dyndns) {
1072
			if (!empty($int) && $int != $dyndns['interface'])
1073
				continue;
1074

    
1075
			services_dyndns_configure_client($dyndns);
1076

    
1077
			sleep(1);
1078
		}
1079

    
1080
		if ($g['booting'])
1081
			echo gettext("done.") . "\n";
1082
	}
1083

    
1084
	return 0;
1085
}
1086

    
1087
function services_dnsmasq_configure() {
1088
	global $config, $g;
1089
	$return = 0;
1090
	
1091
	if(isset($config['system']['developerspew'])) {
1092
		$mt = microtime();
1093
		echo "services_dnsmasq_configure() being called $mt\n";
1094
	}
1095

    
1096
	/* kill any running dnsmasq */
1097
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1098

    
1099
	if (isset($config['dnsmasq']['enable'])) {
1100

    
1101
		if ($g['booting'])
1102
			echo gettext("Starting DNS forwarder...");
1103
		else
1104
			sleep(1);
1105

    
1106
		/* generate hosts file */
1107
		if(system_hosts_generate()!=0)
1108
			$return = 1;
1109

    
1110
		$args = "";
1111

    
1112
		if (isset($config['dnsmasq']['regdhcp'])) {
1113
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1114
		}
1115
		
1116
		/* Setup forwarded domains */
1117
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1118
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1119
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1120
			}
1121
		}
1122

    
1123
		/* Allow DNS Rebind for forwarded domains */
1124
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1125
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1126
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1127
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1128
				}
1129
			}
1130
		}
1131

    
1132
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1133
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1134

    
1135
		if ($config['dnsmasq']['custom_options']) {
1136
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1137
				$args .= " --$c";
1138
		}
1139

    
1140
		/* run dnsmasq */
1141
		mwexec_bg("/usr/local/sbin/dnsmasq --local-ttl 1 --all-servers {$dns_rebind} --dns-forward-max=5000 --cache-size=10000 {$args}");
1142

    
1143
		if ($g['booting'])
1144
			echo gettext("done.") . "\n";
1145
	}
1146

    
1147
	if (!$g['booting']) {
1148
		if(services_dhcpd_configure()!=0)
1149
			$return = 1;
1150
	}
1151

    
1152
	return $return;
1153
}
1154

    
1155
function services_snmpd_configure() {
1156
	global $config, $g;
1157
	if(isset($config['system']['developerspew'])) {
1158
		$mt = microtime();
1159
		echo "services_snmpd_configure() being called $mt\n";
1160
	}
1161

    
1162
	/* kill any running snmpd */
1163
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1164
	sleep(2);
1165
	if(is_process_running("bsnmpd")) 
1166
		mwexec("/usr/bin/killall bsnmpd", true);
1167

    
1168
	if (isset($config['snmpd']['enable'])) {
1169

    
1170
		if ($g['booting'])
1171
			echo gettext("Starting SNMP daemon... ");
1172

    
1173
		/* generate snmpd.conf */
1174
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1175
		if (!$fd) {
1176
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1177
			return 1;
1178
		}
1179

    
1180

    
1181
		$snmpdconf = <<<EOD
1182
location := "{$config['snmpd']['syslocation']}"
1183
contact := "{$config['snmpd']['syscontact']}"
1184
read := "{$config['snmpd']['rocommunity']}"
1185

    
1186
EOD;
1187

    
1188
/* No docs on what write strings do there for disable for now.
1189
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1190
		    $snmpdconf .= <<<EOD
1191
# write string
1192
write := "{$config['snmpd']['rwcommunity']}"
1193

    
1194
EOD;
1195
		}
1196
*/
1197

    
1198

    
1199
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1200
		    $snmpdconf .= <<<EOD
1201
# SNMP Trap support.
1202
traphost := {$config['snmpd']['trapserver']}
1203
trapport := {$config['snmpd']['trapserverport']}
1204
trap := "{$config['snmpd']['trapstring']}"
1205

    
1206

    
1207
EOD;
1208
		}
1209

    
1210

    
1211
		$snmpdconf .= <<<EOD
1212
system := 1     # pfSense
1213
%snmpd
1214
begemotSnmpdDebugDumpPdus       = 2
1215
begemotSnmpdDebugSyslogPri      = 7
1216
begemotSnmpdCommunityString.0.1 = $(read)
1217

    
1218
EOD;
1219

    
1220
/* No docs on what write strings do there for disable for now.
1221
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1222
		    $snmpdconf .= <<<EOD
1223
begemotSnmpdCommunityString.0.2 = $(write)
1224

    
1225
EOD;
1226
		}
1227
*/
1228

    
1229

    
1230
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1231
		    $snmpdconf .= <<<EOD
1232
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1233
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1234
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1235

    
1236
EOD;
1237
		}
1238

    
1239

    
1240
		$snmpdconf .= <<<EOD
1241
begemotSnmpdCommunityDisable    = 1
1242

    
1243
EOD;
1244

    
1245
		if(isset($config['snmpd']['bindlan'])) {
1246
			$bind_to_ip = get_interface_ip("lan");
1247
		} else {
1248
			$bind_to_ip = "0.0.0.0";
1249
		}
1250

    
1251
		if(is_port( $config['snmpd']['pollport'] )) {
1252
		    $snmpdconf .= <<<EOD
1253
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1254

    
1255
EOD;
1256

    
1257
		}
1258

    
1259
		$snmpdconf .= <<<EOD
1260
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1261
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1262

    
1263
# These are bsnmp macros not php vars.
1264
sysContact      = $(contact)
1265
sysLocation     = $(location)
1266
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1267

    
1268
snmpEnableAuthenTraps = 2
1269

    
1270
EOD;
1271

    
1272
		if (is_array( $config['snmpd']['modules'] )) {
1273
		    if(isset($config['snmpd']['modules']['mibii'])) {
1274
			$snmpdconf .= <<<EOD
1275
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1276

    
1277
EOD;
1278
		    }
1279

    
1280
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1281
			$snmpdconf .= <<<EOD
1282
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1283
%netgraph
1284
begemotNgControlNodeName = "snmpd"
1285

    
1286
EOD;
1287
		    }
1288

    
1289
		    if(isset($config['snmpd']['modules']['pf'])) {
1290
			$snmpdconf .= <<<EOD
1291
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1292

    
1293
EOD;
1294
		    }
1295

    
1296
		    if(isset($config['snmpd']['modules']['hostres'])) {
1297
			$snmpdconf .= <<<EOD
1298
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1299

    
1300
EOD;
1301
		    }
1302
		    if(isset($config['snmpd']['modules']['bridge'])) {
1303
			$snmpdconf .= <<<EOD
1304
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1305
# config must end with blank line
1306

    
1307

    
1308
EOD;
1309
		    }
1310
		}
1311

    
1312
		fwrite($fd, $snmpdconf);
1313
		fclose($fd);
1314

    
1315
		if (isset($config['snmpd']['bindlan'])) {
1316
			$bindlan = "";
1317
		}
1318

    
1319
		/* run bsnmpd */
1320
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1321
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1322

    
1323
		if ($g['booting'])
1324
			echo gettext("done.") . "\n";
1325
	}
1326

    
1327
	return 0;
1328
}
1329

    
1330
function services_dnsupdate_process($int = "") {
1331
	global $config, $g;
1332
	if(isset($config['system']['developerspew'])) {
1333
		$mt = microtime();
1334
		echo "services_dnsupdate_process() being called $mt\n";
1335
	}
1336

    
1337
	/* Dynamic DNS updating active? */
1338
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1339
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1340
			if (!isset($dnsupdate['enable']))
1341
				continue;
1342
			if (!empty($int) && $int != $dnsupdate['interface'])
1343
				continue;
1344

    
1345
			/* determine interface name */
1346
			$if = get_real_interface($dnsupdate['interface']);
1347
			$wanip = get_interface_ip($dnsupdate['interface']);
1348
			if ($wanip) {
1349

    
1350
				$keyname = $dnsupdate['keyname'];
1351
				/* trailing dot */
1352
				if (substr($keyname, -1) != ".")
1353
					$keyname .= ".";
1354

    
1355
				$hostname = $dnsupdate['host'];
1356
				/* trailing dot */
1357
				if (substr($hostname, -1) != ".")
1358
					$hostname .= ".";
1359

    
1360
				/* write private key file
1361
				   this is dumb - public and private keys are the same for HMAC-MD5,
1362
				   but nsupdate insists on having both */
1363
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1364
				$privkey .= <<<EOD
1365
Private-key-format: v1.2
1366
Algorithm: 157 (HMAC)
1367
Key: {$dnsupdate['keydata']}
1368

    
1369
EOD;
1370
				fwrite($fd, $privkey);
1371
				fclose($fd);
1372

    
1373
				/* write public key file */
1374
				if ($dnsupdate['keytype'] == "zone") {
1375
					$flags = 257;
1376
					$proto = 3;
1377
				} else if ($dnsupdate['keytype'] == "host") {
1378
					$flags = 513;
1379
					$proto = 3;
1380
				} else if ($dnsupdate['keytype'] == "user") {
1381
					$flags = 0;
1382
					$proto = 2;
1383
				}
1384

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

    
1389
				/* generate update instructions */
1390
				$upinst = "";
1391
				if (!empty($dnsupdate['server']))
1392
					$upinst .= "server {$dnsupdate['server']}\n";
1393
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1394
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1395
				$upinst .= "\n";	/* mind that trailing newline! */
1396

    
1397
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1398
				fwrite($fd, $upinst);
1399
				fclose($fd);
1400

    
1401
				/* invoke nsupdate */
1402
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1403
				if (isset($dnsupdate['usetcp']))
1404
					$cmd .= " -v";
1405
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1406
	
1407
				mwexec_bg($cmd);
1408
			}
1409
		}
1410
	}
1411

    
1412
	return 0;
1413
}
1414

    
1415
function setup_wireless_olsr() {
1416
	global $config, $g;
1417
	if ($g['platform'] == 'jail' || !$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1418
		return;
1419
	if(isset($config['system']['developerspew'])) {
1420
		$mt = microtime();
1421
		echo "setup_wireless_olsr($interface) being called $mt\n";
1422
	}
1423
	conf_mount_rw();
1424
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1425
		$olsr_enable = $olsrd['enable'];
1426
		if($olsr_enable <> "on") {
1427
			if (is_process_running("olsrd"))
1428
				mwexec("/usr/bin/killall olsrd", true);
1429
			return;
1430
		}
1431
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1432

    
1433
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1434
			$enableannounce .= "\nHna4\n";
1435
			$enableannounce .= "{\n";
1436
		if($olsrd['announcedynamicroute'])
1437
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1438
		if($olsrd['enableannounce'] == "on")
1439
			$enableannounce .= "0.0.0.0 0.0.0.0";
1440
			$enableannounce .= "\n}\n";
1441
		} else {
1442
			$enableannounce = "";
1443
		}
1444

    
1445
		$olsr .= <<<EODA
1446
#
1447
# olsr.org OLSR daemon config file
1448
#
1449
# Lines starting with a # are discarded
1450
#
1451
# This file was generated by setup_wireless_olsr() in services.inc
1452
#
1453

    
1454
# This file is an example of a typical
1455
# configuration for a mostly static
1456
# network(regarding mobility) using
1457
# the LQ extention
1458

    
1459
# Debug level(0-9)
1460
# If set to 0 the daemon runs in the background
1461

    
1462
DebugLevel	2
1463

    
1464
# IP version to use (4 or 6)
1465

    
1466
IpVersion	4
1467

    
1468
# Clear the screen each time the internal state changes
1469

    
1470
ClearScreen     yes
1471

    
1472
{$enableannounce}
1473

    
1474
# Should olsrd keep on running even if there are
1475
# no interfaces available? This is a good idea
1476
# for a PCMCIA/USB hotswap environment.
1477
# "yes" OR "no"
1478

    
1479
AllowNoInt	yes
1480

    
1481
# TOS(type of service) value for
1482
# the IP header of control traffic.
1483
# If not set it will default to 16
1484

    
1485
#TosValue	16
1486

    
1487
# The fixed willingness to use(0-7)
1488
# If not set willingness will be calculated
1489
# dynamically based on battery/power status
1490
# if such information is available
1491

    
1492
#Willingness    	4
1493

    
1494
# Allow processes like the GUI front-end
1495
# to connect to the daemon.
1496

    
1497
IpcConnect
1498
{
1499
     # Determines how many simultaneously
1500
     # IPC connections that will be allowed
1501
     # Setting this to 0 disables IPC
1502

    
1503
     MaxConnections  0
1504

    
1505
     # By default only 127.0.0.1 is allowed
1506
     # to connect. Here allowed hosts can
1507
     # be added
1508

    
1509
     Host            127.0.0.1
1510
     #Host            10.0.0.5
1511

    
1512
     # You can also specify entire net-ranges
1513
     # that are allowed to connect. Multiple
1514
     # entries are allowed
1515

    
1516
     #Net             192.168.1.0 255.255.255.0
1517
}
1518

    
1519
# Wether to use hysteresis or not
1520
# Hysteresis adds more robustness to the
1521
# link sensing but delays neighbor registration.
1522
# Used by default. 'yes' or 'no'
1523

    
1524
UseHysteresis	no
1525

    
1526
# Hysteresis parameters
1527
# Do not alter these unless you know
1528
# what you are doing!
1529
# Set to auto by default. Allowed
1530
# values are floating point values
1531
# in the interval 0,1
1532
# THR_LOW must always be lower than
1533
# THR_HIGH.
1534

    
1535
#HystScaling	0.50
1536
#HystThrHigh	0.80
1537
#HystThrLow	0.30
1538

    
1539

    
1540
# Link quality level
1541
# 0 = do not use link quality
1542
# 1 = use link quality for MPR selection
1543
# 2 = use link quality for MPR selection and routing
1544
# Defaults to 0
1545

    
1546
LinkQualityLevel	{$olsrd['enablelqe']}
1547

    
1548
# Link quality window size
1549
# Defaults to 10
1550

    
1551
LinkQualityWinSize	10
1552

    
1553
# Polling rate in seconds(float).
1554
# Default value 0.05 sec
1555

    
1556
Pollrate	0.05
1557

    
1558

    
1559
# TC redundancy
1560
# Specifies how much neighbor info should
1561
# be sent in TC messages
1562
# Possible values are:
1563
# 0 - only send MPR selectors
1564
# 1 - send MPR selectors and MPRs
1565
# 2 - send all neighbors
1566
#
1567
# defaults to 0
1568

    
1569
TcRedundancy	2
1570

    
1571
#
1572
# MPR coverage
1573
# Specifies how many MPRs a node should
1574
# try select to reach every 2 hop neighbor
1575
#
1576
# Can be set to any integer >0
1577
#
1578
# defaults to 1
1579

    
1580
MprCoverage	3
1581

    
1582
# Example plugin entry with parameters:
1583

    
1584
EODA;
1585

    
1586
if($olsrd['enablehttpinfo'] == "on") {
1587
	$olsr .= <<<EODB
1588

    
1589
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1590
{
1591
    PlParam     "port"   "{$olsrd['port']}"
1592
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1593
}
1594

    
1595
EODB;
1596

    
1597
}
1598

    
1599
if($olsrd['enabledsecure'] == "on") {
1600
	$olsr .= <<<EODC
1601

    
1602
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1603
{
1604
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1605
}
1606

    
1607
EODC;
1608

    
1609
}
1610

    
1611
if($olsrd['enabledyngw'] == "on") {
1612

    
1613
	/* unset default route, olsr auto negotiates */
1614
	mwexec("/sbin/route delete default");
1615

    
1616
	$olsr .= <<<EODE
1617

    
1618
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1619
{
1620
    # how often to look for a inet gw, in seconds
1621
    # defaults to 5 secs, if commented out
1622
    PlParam     "Interval"   "{$olsrd['polling']}"
1623

    
1624
    # if one or more IPv4 addresses are given, do a ping on these in
1625
    # descending order to validate that there is not only an entry in
1626
    # routing table, but also a real internet connection. If any of
1627
    # these addresses could be pinged successfully, the test was
1628
    # succesful, i.e. if the ping on the 1st address was successful,the
1629
    # 2nd won't be pinged
1630
    PlParam     "Ping"       "{$olsrd['ping']}"
1631
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1632
}
1633

    
1634
EODE;
1635

    
1636
}
1637

    
1638
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1639
	$interfaces = explode(',', $conf['iface_array']);
1640
	foreach($interfaces as $interface) {
1641
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1642
$olsr .= <<<EODAD
1643
Interface "{$realinterface}"
1644
{
1645

    
1646
    # Hello interval in seconds(float)
1647
    HelloInterval    2.0
1648

    
1649
    # HELLO validity time
1650
    HelloValidityTime	20.0
1651

    
1652
    # TC interval in seconds(float)
1653
    TcInterval        5.0
1654

    
1655
    # TC validity time
1656
    TcValidityTime	30.0
1657

    
1658
    # MID interval in seconds(float)
1659
    MidInterval	5.0
1660

    
1661
    # MID validity time
1662
    MidValidityTime	30.0
1663

    
1664
    # HNA interval in seconds(float)
1665
    HnaInterval	5.0
1666

    
1667
    # HNA validity time
1668
    HnaValidityTime 	30.0
1669

    
1670
    # When multiple links exist between hosts
1671
    # the weight of interface is used to determine
1672
    # the link to use. Normally the weight is
1673
    # automatically calculated by olsrd based
1674
    # on the characteristics of the interface,
1675
    # but here you can specify a fixed value.
1676
    # Olsrd will choose links with the lowest value.
1677

    
1678
    # Weight 0
1679

    
1680

    
1681
}
1682

    
1683
EODAD;
1684

    
1685
	}
1686
	break;
1687
}
1688
		fwrite($fd, $olsr);
1689
		fclose($fd);
1690
	}
1691

    
1692
	if (is_process_running("olsrd"))
1693
		mwexec("/usr/bin/killall olsrd", true);
1694

    
1695
	sleep(2);
1696

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

    
1699
	conf_mount_ro();
1700
}
1701

    
1702
/* configure cron service */
1703
function configure_cron() {
1704
	global $g, $config;
1705

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

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

    
1745
	/* do a HUP kill to force sync changes */
1746
	exec('/bin/pkill -HUP cron');
1747

    
1748
	conf_mount_ro();
1749
}
1750

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

    
1774
function upnp_start() {
1775
	global $config;
1776

    
1777
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1778
		return;
1779

    
1780
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1781
		echo gettext("Starting UPnP service... ");
1782
		require_once('/usr/local/pkg/miniupnpd.inc');
1783
		sync_package_miniupnpd();
1784
		echo "done.\n";
1785
	}
1786
}
1787

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

    
1791
	$is_installed = false;
1792

    
1793
	if(!$config['cron']['item'])
1794
		return;
1795

    
1796
	$x=0;
1797
	foreach($config['cron']['item'] as $item) {
1798
		if(strstr($item['command'], $command)) {
1799
			$is_installed = true;
1800
			break;
1801
		}
1802
		$x++;
1803
	}
1804

    
1805
	if($active) {
1806
		$cron_item = array();
1807
		$cron_item['minute'] = $minute;
1808
		$cron_item['hour'] = $hour;
1809
		$cron_item['mday'] = $monthday;
1810
		$cron_item['month'] = $month;
1811
		$cron_item['wday'] = $weekday;
1812
		$cron_item['who'] = $who;
1813
		$cron_item['command'] = $command;
1814
		if(!$is_installed) {
1815
			$config['cron']['item'][] = $cron_item;
1816
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
1817
		} else {
1818
			$config['cron']['item'][$x] = $cron_item;
1819
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
1820
		}
1821
	} else {
1822
		if(($is_installed == true) && ($x > 0)) {
1823
			unset($config['cron']['item'][$x]);
1824
			write_config(sprintf(gettext("Remvoed cron job for %s"), $command));
1825
		}
1826
	}
1827
	configure_cron();
1828
}
1829

    
1830
?>
(44-44/61)