Project

General

Profile

Download (49.7 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
        :pinfoflags#64: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("DHCP leases restore failed exited with $dhcpreturn, the error is: $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 "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("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().\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("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 "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("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("Started Igmpproxy service sucsesfully.");
912

    
913
        return 0;
914
}
915

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

    
923
        $ifcfg = $config['interfaces'][$if];
924

    
925
	if (empty($if) || empty($ifcfg['if']))
926
		return 0;
927

    
928
        /* Enable staticarp, if enabled */
929
        if(isset($config['dhcpd'][$if]['staticarp'])) {
930
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
931
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
932
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
933

    
934
                        foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
935
                                mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
936

    
937
                        }
938

    
939
                }
940
        } else {
941
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
942
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
943
        }
944

    
945
        return 0;
946
}
947

    
948
function services_dhcrelay_configure() {
949
	global $config, $g;
950
	if(isset($config['system']['developerspew'])) {
951
		$mt = microtime();
952
		echo "services_dhcrelay_configure() being called $mt\n";
953
	}
954

    
955
	/* kill any running dhcrelay */
956
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
957

    
958
	$dhcrelaycfg =& $config['dhcrelay'];
959

    
960
	/* DHCPRelay enabled on any interfaces? */
961
	if (!isset($dhcrelaycfg['enable']))
962
		return 0;
963

    
964
	if ($g['booting'])
965
		echo "Starting DHCP relay service...";
966
	else
967
		sleep(1);
968

    
969
	$iflist = get_configured_interface_list();
970

    
971
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
972
	foreach ($dhcifaces as $dhcrelayif) {
973
		if (!isset($iflist[$dhcrelayif]) ||
974
			link_interface_to_bridge($dhcrelayif))
975
			continue;
976

    
977
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
978
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
979
	}
980

    
981
	/* 
982
	 * In order for the relay to work, it needs to be active
983
	 * on the interface in which the destination server sits.
984
	 */
985
	$srvips = explode(",", $dhcrelaycfg['server']);
986
	foreach ($srvips as $srcidx => $srvip) {
987
		unset($destif);
988
		foreach ($iflist as $ifname) {
989
			$subnet = get_interface_ip($ifname);
990
			if (!is_ipaddr($subnet))
991
				continue;
992
			$subnet .=  "/" . get_interface_subnet($ifname);
993
			if (ip_in_subnet($srvip, $subnet)) {
994
				$destif = get_real_interface($ifname);
995
				break;
996
			}
997
		}
998
		if (!isset($destif)) {
999
			if (is_array($config['staticroutes']['route'])) {
1000
				foreach ($config['staticroutes']['route'] as $rtent) {
1001
					if (ip_in_subnet($srvip, $rtent['network'])) {
1002
						$a_gateways = return_gateways_array(true);
1003
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1004
						break;
1005
					}
1006
				}
1007
			}
1008
		}
1009

    
1010
		if (!isset($destif)) {
1011
			/* Create a array from the existing route table */
1012
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
1013
        		array_shift($route_str);
1014
        		array_shift($route_str);
1015
        		array_shift($route_str);
1016
        		array_shift($route_str);
1017
        		$route_arr = array();
1018
        		foreach($route_str as $routeline) {
1019
                		$items = preg_split("/[ ]+/i", $routeline);
1020
				if (ip_in_subnet($srvip, $items[0])) {
1021
					$destif = trim($items[2]);
1022
					break;
1023
				}
1024
        		}
1025
		}
1026
	
1027
		if (!isset($destif)) {
1028
			if (is_array($config['gateways']['gateway_item'])) {
1029
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1030
					if (isset($gateway['defaultgw'])) {
1031
						$a_gateways = return_gateways_array(true);
1032
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1033
						break;
1034
					}		
1035
				}
1036
			} else
1037
				$destif = get_real_interface("wan");
1038
		}
1039

    
1040
		if (!empty($destif))
1041
			$dhcrelayifs[] = $destif;
1042
	}
1043
	$dhcrelayifs = array_unique($dhcrelayifs);
1044

    
1045
	/* fire up dhcrelay */
1046
	if (empty($dhcrelayifs)) {
1047
		log_error("No suitable interface found for running dhcrelay!");
1048
		return; /* XXX */
1049
	}
1050

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

    
1053
	if (isset($dhcrelaycfg['agentoption']))
1054
		$cmd .=  " -a -m replace";
1055

    
1056
	$cmd .= " " . implode(" ", $srvips);
1057
	mwexec($cmd);
1058

    
1059
	return 0;
1060
}
1061

    
1062
function services_dyndns_configure_client($conf) {
1063

    
1064
	if (!isset($conf['enable']))
1065
		return;
1066

    
1067
	/* load up the dyndns.class */
1068
	require_once("dyndns.class");
1069

    
1070
	log_error("DynDns: Running updatedns()");
1071

    
1072
	$dns = new updatedns($dnsService = $conf['type'],
1073
		$dnsHost = $conf['host'],
1074
		$dnsUser = $conf['username'],
1075
		$dnsPass = $conf['password'],
1076
		$dnsWilcard = $conf['wildcard'],
1077
		$dnsMX = $conf['mx'], 
1078
		$dnsIf = "{$conf['interface']}");
1079

    
1080
}
1081

    
1082
function services_dyndns_configure($int = "") {
1083
	global $config, $g;
1084
	if(isset($config['system']['developerspew'])) {
1085
		$mt = microtime();
1086
		echo "services_dyndns_configure() being called $mt\n";
1087
	}
1088

    
1089
	$dyndnscfg = $config['dyndnses']['dyndns'];
1090

    
1091
	if (is_array($dyndnscfg)) {
1092
		if ($g['booting']) 
1093
			echo "Starting DynDNS clients...";
1094

    
1095
		foreach ($dyndnscfg as $dyndns) {
1096
			if (!empty($int) && $int != $dyndns['interface'])
1097
				continue;
1098

    
1099
			services_dyndns_configure_client($dyndns);
1100

    
1101
			sleep(1);
1102
		}
1103

    
1104
		if ($g['booting'])
1105
			echo "done.\n";
1106
	}
1107

    
1108
	return 0;
1109
}
1110

    
1111
function services_dnsmasq_configure() {
1112
	global $config, $g;
1113
	$return = 0;
1114
	
1115
	if(isset($config['system']['developerspew'])) {
1116
		$mt = microtime();
1117
		echo "services_dnsmasq_configure() being called $mt\n";
1118
	}
1119

    
1120
	/* kill any running dnsmasq */
1121
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1122

    
1123
	if (isset($config['dnsmasq']['enable'])) {
1124

    
1125
		if ($g['booting'])
1126
			echo "Starting DNS forwarder...";
1127
		else
1128
			sleep(1);
1129

    
1130
		/* generate hosts file */
1131
		if(system_hosts_generate()!=0)
1132
			$return = 1;
1133

    
1134
		$args = "";
1135

    
1136
		if (isset($config['dnsmasq']['regdhcp'])) {
1137
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1138
		}
1139
		
1140
		/* Setup forwarded domains */
1141
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1142
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1143
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1144
			}
1145
		}
1146

    
1147
		/* Allow DNS Rebind for forwarded domains */
1148
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1149
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1150
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1151
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1152
				}
1153
			}
1154
		}
1155

    
1156
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1157
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1158

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

    
1162
		if ($g['booting'])
1163
			echo "done.\n";
1164
	}
1165

    
1166
	if (!$g['booting']) {
1167
		if(services_dhcpd_configure()!=0)
1168
			$return = 1;
1169
	}
1170

    
1171
	return $return;
1172
}
1173

    
1174
function services_snmpd_configure() {
1175
	global $config, $g;
1176
	if(isset($config['system']['developerspew'])) {
1177
		$mt = microtime();
1178
		echo "services_snmpd_configure() being called $mt\n";
1179
	}
1180

    
1181
	/* kill any running snmpd */
1182
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1183
	sleep(2);
1184
	if(is_process_running("bsnmpd")) 
1185
		mwexec("/usr/bin/killall bsnmpd", true);
1186

    
1187
	if (isset($config['snmpd']['enable'])) {
1188

    
1189
		if ($g['booting'])
1190
			echo "Starting SNMP daemon... ";
1191

    
1192
		/* generate snmpd.conf */
1193
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1194
		if (!$fd) {
1195
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
1196
			return 1;
1197
		}
1198

    
1199

    
1200
		$snmpdconf = <<<EOD
1201
location := "{$config['snmpd']['syslocation']}"
1202
contact := "{$config['snmpd']['syscontact']}"
1203
read := "{$config['snmpd']['rocommunity']}"
1204

    
1205
EOD;
1206

    
1207
/* No docs on what write strings do there for disable for now.
1208
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1209
		    $snmpdconf .= <<<EOD
1210
# write string
1211
write := "{$config['snmpd']['rwcommunity']}"
1212

    
1213
EOD;
1214
		}
1215
*/
1216

    
1217

    
1218
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1219
		    $snmpdconf .= <<<EOD
1220
# SNMP Trap support.
1221
traphost := {$config['snmpd']['trapserver']}
1222
trapport := {$config['snmpd']['trapserverport']}
1223
trap := "{$config['snmpd']['trapstring']}"
1224

    
1225

    
1226
EOD;
1227
		}
1228

    
1229

    
1230
		$snmpdconf .= <<<EOD
1231
system := 1     # pfSense
1232
%snmpd
1233
begemotSnmpdDebugDumpPdus       = 2
1234
begemotSnmpdDebugSyslogPri      = 7
1235
begemotSnmpdCommunityString.0.1 = $(read)
1236

    
1237
EOD;
1238

    
1239
/* No docs on what write strings do there for disable for now.
1240
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1241
		    $snmpdconf .= <<<EOD
1242
begemotSnmpdCommunityString.0.2 = $(write)
1243

    
1244
EOD;
1245
		}
1246
*/
1247

    
1248

    
1249
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1250
		    $snmpdconf .= <<<EOD
1251
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1252
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1253
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1254

    
1255
EOD;
1256
		}
1257

    
1258

    
1259
		$snmpdconf .= <<<EOD
1260
begemotSnmpdCommunityDisable    = 1
1261

    
1262
EOD;
1263

    
1264
		if(isset($config['snmpd']['bindlan'])) {
1265
			$bind_to_ip = get_interface_ip("lan");
1266
		} else {
1267
			$bind_to_ip = "0.0.0.0";
1268
		}
1269

    
1270
		if(is_port( $config['snmpd']['pollport'] )) {
1271
		    $snmpdconf .= <<<EOD
1272
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1273

    
1274
EOD;
1275

    
1276
		}
1277

    
1278
		$snmpdconf .= <<<EOD
1279
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1280
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1281

    
1282
# These are bsnmp macros not php vars.
1283
sysContact      = $(contact)
1284
sysLocation     = $(location)
1285
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1286

    
1287
snmpEnableAuthenTraps = 2
1288

    
1289
EOD;
1290

    
1291
		if (is_array( $config['snmpd']['modules'] )) {
1292
		    if(isset($config['snmpd']['modules']['mibii'])) {
1293
			$snmpdconf .= <<<EOD
1294
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1295

    
1296
EOD;
1297
		    }
1298

    
1299
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1300
			$snmpdconf .= <<<EOD
1301
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1302
%netgraph
1303
begemotNgControlNodeName = "snmpd"
1304

    
1305
EOD;
1306
		    }
1307

    
1308
		    if(isset($config['snmpd']['modules']['pf'])) {
1309
			$snmpdconf .= <<<EOD
1310
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1311

    
1312
EOD;
1313
		    }
1314

    
1315
		    if(isset($config['snmpd']['modules']['hostres'])) {
1316
			$snmpdconf .= <<<EOD
1317
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1318

    
1319
EOD;
1320
		    }
1321
		    if(isset($config['snmpd']['modules']['bridge'])) {
1322
			$snmpdconf .= <<<EOD
1323
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1324
# config must end with blank line
1325

    
1326

    
1327
EOD;
1328
		    }
1329
		}
1330

    
1331
		fwrite($fd, $snmpdconf);
1332
		fclose($fd);
1333

    
1334
		if (isset($config['snmpd']['bindlan'])) {
1335
			$bindlan = "";
1336
		}
1337

    
1338
		/* run bsnmpd */
1339
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1340
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1341

    
1342
		if ($g['booting'])
1343
			echo "done.\n";
1344
	}
1345

    
1346
	return 0;
1347
}
1348

    
1349
function services_dnsupdate_process($int = "") {
1350
	global $config, $g;
1351
	if(isset($config['system']['developerspew'])) {
1352
		$mt = microtime();
1353
		echo "services_dnsupdate_process() being called $mt\n";
1354
	}
1355

    
1356
	/* Dynamic DNS updating active? */
1357
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1358
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1359
			if (!isset($dnsupdate['enable']))
1360
				continue;
1361
			if (!empty($int) && $int != $dnsupdate['interface'])
1362
				continue;
1363

    
1364
			/* determine interface name */
1365
			$if = get_real_interface($dnsupdate['interface']);
1366
			$wanip = get_interface_ip($dnsupdate['interface']);
1367
			if ($wanip) {
1368

    
1369
				$keyname = $dnsupdate['keyname'];
1370
				/* trailing dot */
1371
				if (substr($keyname, -1) != ".")
1372
					$keyname .= ".";
1373

    
1374
				$hostname = $dnsupdate['host'];
1375
				/* trailing dot */
1376
				if (substr($hostname, -1) != ".")
1377
					$hostname .= ".";
1378

    
1379
				/* write private key file
1380
				   this is dumb - public and private keys are the same for HMAC-MD5,
1381
				   but nsupdate insists on having both */
1382
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1383
				$privkey .= <<<EOD
1384
Private-key-format: v1.2
1385
Algorithm: 157 (HMAC)
1386
Key: {$dnsupdate['keydata']}
1387

    
1388
EOD;
1389
				fwrite($fd, $privkey);
1390
				fclose($fd);
1391

    
1392
				/* write public key file */
1393
				if ($dnsupdate['keytype'] == "zone") {
1394
					$flags = 257;
1395
					$proto = 3;
1396
				} else if ($dnsupdate['keytype'] == "host") {
1397
					$flags = 513;
1398
					$proto = 3;
1399
				} else if ($dnsupdate['keytype'] == "user") {
1400
					$flags = 0;
1401
					$proto = 2;
1402
				}
1403

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

    
1408
				/* generate update instructions */
1409
				$upinst = "";
1410
				if (!empty($dnsupdate['server']))
1411
					$upinst .= "server {$dnsupdate['server']}\n";
1412
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1413
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1414
				$upinst .= "\n";	/* mind that trailing newline! */
1415

    
1416
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1417
				fwrite($fd, $upinst);
1418
				fclose($fd);
1419

    
1420
				/* invoke nsupdate */
1421
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1422
				if (isset($dnsupdate['usetcp']))
1423
					$cmd .= " -v";
1424
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1425
	
1426
				mwexec_bg($cmd);
1427
			}
1428
		}
1429
	}
1430

    
1431
	return 0;
1432
}
1433

    
1434
function setup_wireless_olsr() {
1435
	global $config, $g;
1436
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1437
		return;
1438
	if(isset($config['system']['developerspew'])) {
1439
		$mt = microtime();
1440
		echo "setup_wireless_olsr($interface) being called $mt\n";
1441
	}
1442
	conf_mount_rw();
1443
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1444
		$olsr_enable = $olsrd['enable'];
1445
		if($olsr_enable <> "on")
1446
			return;
1447
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1448

    
1449
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1450
			$enableannounce .= "\nHna4\n";
1451
			$enableannounce .= "{\n";
1452
		if($olsrd['announcedynamicroute'])
1453
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1454
		if($olsrd['enableannounce'] == "on")
1455
			$enableannounce .= "0.0.0.0 0.0.0.0";
1456
			$enableannounce .= "\n}\n";
1457
		} else {
1458
			$enableannounce = "";
1459
		}
1460

    
1461
		$olsr .= <<<EODA
1462
#
1463
# olsr.org OLSR daemon config file
1464
#
1465
# Lines starting with a # are discarded
1466
#
1467
# This file was generated by setup_wireless_olsr() in services.inc
1468
#
1469

    
1470
# This file is an example of a typical
1471
# configuration for a mostly static
1472
# network(regarding mobility) using
1473
# the LQ extention
1474

    
1475
# Debug level(0-9)
1476
# If set to 0 the daemon runs in the background
1477

    
1478
DebugLevel	2
1479

    
1480
# IP version to use (4 or 6)
1481

    
1482
IpVersion	4
1483

    
1484
# Clear the screen each time the internal state changes
1485

    
1486
ClearScreen     yes
1487

    
1488
{$enableannounce}
1489

    
1490
# Should olsrd keep on running even if there are
1491
# no interfaces available? This is a good idea
1492
# for a PCMCIA/USB hotswap environment.
1493
# "yes" OR "no"
1494

    
1495
AllowNoInt	yes
1496

    
1497
# TOS(type of service) value for
1498
# the IP header of control traffic.
1499
# If not set it will default to 16
1500

    
1501
#TosValue	16
1502

    
1503
# The fixed willingness to use(0-7)
1504
# If not set willingness will be calculated
1505
# dynamically based on battery/power status
1506
# if such information is available
1507

    
1508
#Willingness    	4
1509

    
1510
# Allow processes like the GUI front-end
1511
# to connect to the daemon.
1512

    
1513
IpcConnect
1514
{
1515
     # Determines how many simultaneously
1516
     # IPC connections that will be allowed
1517
     # Setting this to 0 disables IPC
1518

    
1519
     MaxConnections  0
1520

    
1521
     # By default only 127.0.0.1 is allowed
1522
     # to connect. Here allowed hosts can
1523
     # be added
1524

    
1525
     Host            127.0.0.1
1526
     #Host            10.0.0.5
1527

    
1528
     # You can also specify entire net-ranges
1529
     # that are allowed to connect. Multiple
1530
     # entries are allowed
1531

    
1532
     #Net             192.168.1.0 255.255.255.0
1533
}
1534

    
1535
# Wether to use hysteresis or not
1536
# Hysteresis adds more robustness to the
1537
# link sensing but delays neighbor registration.
1538
# Used by default. 'yes' or 'no'
1539

    
1540
UseHysteresis	no
1541

    
1542
# Hysteresis parameters
1543
# Do not alter these unless you know
1544
# what you are doing!
1545
# Set to auto by default. Allowed
1546
# values are floating point values
1547
# in the interval 0,1
1548
# THR_LOW must always be lower than
1549
# THR_HIGH.
1550

    
1551
#HystScaling	0.50
1552
#HystThrHigh	0.80
1553
#HystThrLow	0.30
1554

    
1555

    
1556
# Link quality level
1557
# 0 = do not use link quality
1558
# 1 = use link quality for MPR selection
1559
# 2 = use link quality for MPR selection and routing
1560
# Defaults to 0
1561

    
1562
LinkQualityLevel	{$olsrd['enablelqe']}
1563

    
1564
# Link quality window size
1565
# Defaults to 10
1566

    
1567
LinkQualityWinSize	10
1568

    
1569
# Polling rate in seconds(float).
1570
# Default value 0.05 sec
1571

    
1572
Pollrate	0.05
1573

    
1574

    
1575
# TC redundancy
1576
# Specifies how much neighbor info should
1577
# be sent in TC messages
1578
# Possible values are:
1579
# 0 - only send MPR selectors
1580
# 1 - send MPR selectors and MPRs
1581
# 2 - send all neighbors
1582
#
1583
# defaults to 0
1584

    
1585
TcRedundancy	2
1586

    
1587
#
1588
# MPR coverage
1589
# Specifies how many MPRs a node should
1590
# try select to reach every 2 hop neighbor
1591
#
1592
# Can be set to any integer >0
1593
#
1594
# defaults to 1
1595

    
1596
MprCoverage	3
1597

    
1598
# Example plugin entry with parameters:
1599

    
1600
EODA;
1601

    
1602
if($olsrd['enablehttpinfo'] == "on") {
1603
	$olsr .= <<<EODB
1604

    
1605
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1606
{
1607
    PlParam     "port"   "{$olsrd['port']}"
1608
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1609
}
1610

    
1611
EODB;
1612

    
1613
}
1614

    
1615
if($olsrd['enabledsecure'] == "on") {
1616
	$olsr .= <<<EODC
1617

    
1618
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1619
{
1620
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1621
}
1622

    
1623
EODC;
1624

    
1625
}
1626

    
1627
if($olsrd['enabledyngw'] == "on") {
1628

    
1629
	/* unset default route, olsr auto negotiates */
1630
	mwexec("/sbin/route delete default");
1631

    
1632
	$olsr .= <<<EODE
1633

    
1634
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1635
{
1636
    # how often to look for a inet gw, in seconds
1637
    # defaults to 5 secs, if commented out
1638
    PlParam     "Interval"   "{$olsrd['polling']}"
1639

    
1640
    # if one or more IPv4 addresses are given, do a ping on these in
1641
    # descending order to validate that there is not only an entry in
1642
    # routing table, but also a real internet connection. If any of
1643
    # these addresses could be pinged successfully, the test was
1644
    # succesful, i.e. if the ping on the 1st address was successful,the
1645
    # 2nd won't be pinged
1646
    PlParam     "Ping"       "{$olsrd['ping']}"
1647
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1648
}
1649

    
1650
EODE;
1651

    
1652
}
1653

    
1654
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1655
	$interfaces = explode(',', $conf['iface_array']);
1656
	foreach($interfaces as $interface) {
1657
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1658
$olsr .= <<<EODAD
1659
Interface "{$realinterface}"
1660
{
1661

    
1662
    # Hello interval in seconds(float)
1663
    HelloInterval    2.0
1664

    
1665
    # HELLO validity time
1666
    HelloValidityTime	20.0
1667

    
1668
    # TC interval in seconds(float)
1669
    TcInterval        5.0
1670

    
1671
    # TC validity time
1672
    TcValidityTime	30.0
1673

    
1674
    # MID interval in seconds(float)
1675
    MidInterval	5.0
1676

    
1677
    # MID validity time
1678
    MidValidityTime	30.0
1679

    
1680
    # HNA interval in seconds(float)
1681
    HnaInterval	5.0
1682

    
1683
    # HNA validity time
1684
    HnaValidityTime 	30.0
1685

    
1686
    # When multiple links exist between hosts
1687
    # the weight of interface is used to determine
1688
    # the link to use. Normally the weight is
1689
    # automatically calculated by olsrd based
1690
    # on the characteristics of the interface,
1691
    # but here you can specify a fixed value.
1692
    # Olsrd will choose links with the lowest value.
1693

    
1694
    # Weight 0
1695

    
1696

    
1697
}
1698

    
1699
EODAD;
1700

    
1701
	}
1702
	break;
1703
}
1704
		fwrite($fd, $olsr);
1705
		fclose($fd);
1706
	}
1707

    
1708
	if(is_process_running("olsrd"))
1709
		mwexec("/usr/bin/killall olsrd", true);
1710

    
1711
	sleep(2);
1712

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

    
1715
	conf_mount_ro();
1716
}
1717

    
1718
/* configure cron service */
1719
function configure_cron() {
1720
	global $g, $config;
1721

    
1722
	conf_mount_rw();
1723
	/* preserve existing crontab entries */
1724
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1725
	
1726
	for ($i = 0; $i < count($crontab_contents); $i++) {
1727
		$cron_item =& $crontab_contents[$i];
1728
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
1729
			array_splice($crontab_contents, $i - 1);
1730
			break;
1731
		}
1732
	}
1733
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
1734
	
1735
	
1736
	if (is_array($config['cron']['item'])) {
1737
		$crontab_contents .= "#\n";
1738
		$crontab_contents .= "# pfSense specific crontab entries\n";
1739
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1740
		$crontab_contents .= "#\n";
1741

    
1742
		foreach ($config['cron']['item'] as $item) {
1743
			$crontab_contents .= "\n{$item['minute']}\t";
1744
			$crontab_contents .= "{$item['hour']}\t";
1745
			$crontab_contents .= "{$item['mday']}\t";
1746
			$crontab_contents .= "{$item['month']}\t";
1747
			$crontab_contents .= "{$item['wday']}\t";
1748
			$crontab_contents .= "{$item['who']}\t";
1749
			$crontab_contents .= "{$item['command']}";
1750
		}
1751
    
1752
		$crontab_contents .= "\n#\n";
1753
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1754
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1755
		$crontab_contents .= "#\n\n";
1756
	}
1757
	
1758
	/* please maintain the newline at the end of file */
1759
	file_put_contents("/etc/crontab", $crontab_contents);
1760

    
1761
	/* do a HUP kill to force sync changes */
1762
	exec('/bin/pkill -HUP cron');
1763

    
1764
	conf_mount_ro();
1765
}
1766

    
1767
function upnp_action ($action) {
1768
	switch($action) {
1769
		case "start":
1770
			if (file_exists('/var/etc/miniupnpd.conf')) {
1771
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
1772
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
1773
			}
1774
			break;
1775
		case "stop":
1776
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
1777
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
1778
				mwexec('killall miniupnpd 2>/dev/null', true);
1779
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1780
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1781
			break;
1782
		case "restart":
1783
			upnp_action('stop');
1784
			upnp_action('start');
1785
			break;
1786
	}
1787
}
1788

    
1789
function upnp_start() {
1790
	global $config;
1791

    
1792
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1793
		return;
1794

    
1795
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1796
		echo "Starting UPnP service... ";
1797
		require_once('/usr/local/pkg/miniupnpd.inc');
1798
		sync_package_miniupnpd();
1799
		echo "done.\n";
1800
	}
1801
}
1802

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

    
1806
	$is_installed = false;
1807

    
1808
	if(!$config['cron']['item'])
1809
		return;
1810

    
1811
	$x=0;
1812
	foreach($config['cron']['item'] as $item) {
1813
		if(strstr($item['command'], $command)) {
1814
			$is_installed = true;
1815
			break;
1816
		}
1817
		$x++;
1818
	}
1819

    
1820
	if($active) {
1821
		$cron_item = array();
1822
		$cron_item['minute'] = $minute;
1823
		$cron_item['hour'] = $hour;
1824
		$cron_item['mday'] = $monthday;
1825
		$cron_item['month'] = $month;
1826
		$cron_item['wday'] = $weekday;
1827
		$cron_item['who'] = $who;
1828
		$cron_item['command'] = $command;
1829
		if(!$is_installed) {
1830
			$config['cron']['item'][] = $cron_item;
1831
			write_config("Installed cron job for {$command}");
1832
		} else {
1833
			$config['cron']['item'][$x] = $cron_item;
1834
			write_config("Updated cron job for {$command}");
1835
		}
1836
	} else {
1837
		if(($is_installed == true) && ($x > 0)) {
1838
			unset($config['cron']['item'][$x]);
1839
			write_config("Remvoed cron job for {$command}");
1840
		}
1841
	}
1842
	configure_cron();
1843
}
1844

    
1845
?>
(44-44/61)