Project

General

Profile

Download (58.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	/usr/local/sbin/unbound
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
	/* we need to shut down the rtadvd cleanly, otherwise it will send out the prefix
55
	 * information with a lifetime of 0 to notify clients of a (possible) new prefix */
56
	if(is_process_running("rtadvd")) {
57
		log_error("Shutting down Router Advertisment daemon cleanly");
58
		mwexec("killall rtadvd");
59
	}
60

    
61
	if (!is_array($config['dhcpdv6']))
62
		$config['dhcpdv6'] = array();
63

    
64
	$dhcpdv6cfg = $config['dhcpdv6'];
65
	$Iflist = get_configured_interface_list();
66

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

    
74
	/* raflags, other o, managed=64 m, stateful=128, both=192 */
75
	/* pinfoflags 0 = disable slaac */
76

    
77
	$rtadvdconf = "# Automatically Generated, do not edit\n";
78
	$rtadvdconf = <<<EOD
79

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

    
89
EOD;
90

    
91
	/* Process all links which need the router advertise daemon */
92
	$rtadvdnum = 0;
93
	$rtadvdifs=array();
94

    
95
	/* handle manually configured DHCP6 settings first */
96
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
97
		if($dhcpv6ifconf['mode'] == "disabled")
98
			continue;
99

    
100
		$realif = get_real_interface($dhcpv6if);
101
		$rtadvdifs[] = $realif;
102

    
103
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
104
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
105
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
106
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
107

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

    
127
		}
128
		$rtadvdconf .= "\t:tc=ether:\\\n";
129
		/* add DNS servers */
130
		$dnslist = array();
131
		if(!empty($dhcpv6ifconf['dnsserver'][0])) {
132
			foreach($dhcpv6ifconf['dnsserver'] as $server) {
133
				if(is_ipaddrv6($server))
134
					$dnslist[] = $server;
135
			}
136
		} elseif (isset($config['dnsmasq']['enable'])) {
137
			$dnslist[] = get_interface_ipv6($dhcpv6if);
138
		} elseif (!empty($config['system']['dnsserver'][0])) {
139
			foreach($config['system']['dnsserver'] as $server) {
140
				if(is_ipaddrv6($server))
141
					$dnslist[] = $server;
142
			}
143
		}
144
		if(!empty($dnslist)) {
145
			$dnsstring = implode(",", $dnslist);
146
			$rtadvdconf .= "\t:rdnss=\"{$dnsstring}\":\\\n";
147
		}
148
		if($dhcpv6ifconf['domain'] <> "") {
149
			$rtadvdconf .= "\t:dnssl=\"{$dhcpv6ifconf['domain']}\":\n";
150
		} elseif ($config['system']['domain'] <> "") {
151
			$rtadvdconf .= "\t:dnssl=\"{$config['system']['domain']}\":\n";
152
		}
153
		$rtadvdconf .= "\n\n";
154
		$rtadvdnum++;
155
	}
156

    
157
	/* handle DHCP-PD prefixes */
158
	foreach ($Iflist as $if => $ifdescr) {
159
		if(!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id']))
160
			continue;
161

    
162
		$realif = get_real_interface($if);
163
		/* prevent duplicate entries */
164
		if(in_array($realif, $rtadvdifs))
165
			continue;
166

    
167
		$rtadvdifs[] = $realif;
168

    
169
		$ifcfgipv6 = get_interface_ipv6($if);
170
		$ifcfgsnv6 = get_interface_subnetv6($if);
171
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
172
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
173

    
174
		$dnslist = array();
175
		if(is_ipaddrv6($subnetv6)) {
176
			$rtadvdconf .= "# Generated for DHCP-PD delegation $if\n";
177
			$rtadvdconf .= "{$realif}:\\\n";
178
			/* use lower timers for dhcp-pd */
179
			$rtadvdconf .= "\t:pltime=60:\\\n";
180
			$rtadvdconf .= "\t:pltime=120:\\\n";
181
			$rtadvdconf .= "\t:vltime=180:\\\n";
182
			$rtadvdconf .= "\t:rtltime=60:\\\n";
183
			$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
184
			$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
185
			$rtadvdconf .= "\t:raflags=\"mo\":\\\n";
186
			if (isset($config['dnsmasq']['enable'])) {
187
				$dnslist[] = get_interface_ipv6($dhcpv6if);
188
			} elseif (!empty($config['system']['dnsserver'][0])) {
189
				foreach($config['system']['dnsserver'] as $server) {
190
					if(is_ipaddrv6($server))
191
						$dnslist[] = $server;
192
				}
193
			}
194
			if(!empty($dnslist)) {
195
				$dnsstring = implode(",", $dnslist);
196
				$rtadvdconf .= "\t:rdnss=\"{$dnsstring}\":\\\n";
197
			}
198
			$rtadvdconf .= "\t:tc=ether:\\\n";
199
			$rtadvdconf .= "\n\n"; 
200
			$rtadvdnum++;
201
		}
202
	}
203

    
204
	/* Handle 6RD prefix assignment */
205
	foreach ($Iflist as $if => $ifdescr) {
206
		if(!is_numeric($config['interfaces'][$if]['prefix-6rd-id']))
207
			continue;
208

    
209
		echo "rtadvd config for {$if}\n";
210

    
211
		$realif = get_real_interface($if);
212
		/* prevent duplicate entries */
213
		if(in_array($realif, $rtadvdifs))
214
			continue;
215

    
216
		$rtadvdifs[] = $realif;
217
		
218
		/* find the interface which has the 6RD prefix defined and it's IPv4 address */
219
		foreach($Iflist as $rdif => $rdifdescr) {
220
			if($config['interfaces'][$rdif]['ipaddrv6'] == "6rd") {
221
				$realrdif = get_real_interface("$rdif");
222
				$ip4address = find_interface_ip($realrdif);
223
				echo "rtadvd config found 6RD if {$rdif} address {$ip4address}\n";
224
				if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
225
					log_error("The interface IPv4 '{$ip4address}' address on interface '{$rdif}' is not public, not configuring 6RD prefix on {$if}");
226
					// continue;
227
				}
228
				/* calculate the IPv6 prefix from the public IPv4 address */
229
				$ip4arr = explode(".", $ip4address);
230
				$rd6prefix = explode("/", $config['interfaces'][$rdif]['prefix-6rd']);
231
				$rd6prefix = explode(":", $rd6prefix[0]);
232
				if($config['interfaces'][$rdif]['prefix-6rd-len'] == 0) {
233
					$rd6lanprefixlen = 64;
234
				} else {
235
					log_error("We only support a 64 bit subnet currently");
236
					continue;
237
				}
238
				$rd6lanprefix = sprintf("{$rd6prefix[0]}:{$rd6prefix[1]}:%02x%02x:%02x%02x::", $ip4arr[0], $ip4arr[1], $ip4arr[2], $ip4arr[3]);
239
				$subnetv6 = "{$rd6lanprefix}/{$rd6lanprefixlen}";
240
				// mwexec("/sbin/ifconfig {$realif} inet6 {$rd6lanprefix}1 prefixlen {$rd6lanprefixlen}");
241
			}
242
		}
243

    
244

    
245
		$dnslist = array();
246
		if(is_ipaddrv6($subnetv6)) {
247
			$rtadvdconf .= "# Generated for 6RD on $if\n";
248
			$rtadvdconf .= "{$realif}:\\\n";
249
			/* use lower timers for 6RD prefixes */
250
			$rtadvdconf .= "\t:pltime=60:\\\n";
251
			$rtadvdconf .= "\t:pltime=120:\\\n";
252
			$rtadvdconf .= "\t:vltime=180:\\\n";
253
			$rtadvdconf .= "\t:rtltime=60:\\\n";
254
			$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
255
			$rtadvdconf .= "\t:prefixlen#{$rd6lanprefixlen}:\\\n";
256
			$rtadvdconf .= "\t:raflags=\"mo\":\\\n";
257
			if (isset($config['dnsmasq']['enable'])) {
258
				$dnslist[] = get_interface_ipv6($dhcpv6if);
259
			} elseif (!empty($config['system']['dnsserver'][0])) {
260
				foreach($config['system']['dnsserver'] as $server) {
261
					if(is_ipaddrv6($server))
262
						$dnslist[] = $server;
263
				}
264
			}
265
			if(!empty($dnslist)) {
266
				$dnsstring = implode(",", $dnslist);
267
				$rtadvdconf .= "\t:rdnss=\"{$dnsstring}\":\\\n";
268
			}
269
			$rtadvdconf .= "\t:tc=ether:\\\n";
270
			$rtadvdconf .= "\n\n"; 
271
			$rtadvdnum++;
272
		}
273
	}
274

    
275
	fwrite($fd, $rtadvdconf);
276
	fclose($fd);
277

    
278
	if(count($rtadvdifs) > 0) {
279
		mwexec("/usr/sbin/rtadvd -c {$g['varetc_path']}/rtadvd.conf " . join(" ", $rtadvdifs));
280
	}
281
	return 0;
282
}
283

    
284
function services_dhcpd_configure() {
285
	global $config, $g;
286

    
287
	/* configure DHCPD chroot once */
288
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
289
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
290
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
291
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
292
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
293
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
294
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
295
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
296
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
297
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
298
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
299
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
300
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
301
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
302
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
303
	if(!trim($status))
304
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
305
	fclose($fd);
306
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
307

    
308
	services_dhcpdv4_configure();
309
	services_dhcpdv6_configure();
310
	services_rtadvd_configure();
311
	return;
312

    
313
}
314
function services_dhcpdv4_configure() {
315
	global $config, $g;
316
	
317
	if($g['services_dhcp_server_enable'] == false) 
318
		return;
319

    
320
	if(isset($config['system']['developerspew'])) {
321
		$mt = microtime();
322
		echo "services_dhcpdv4_configure($if) being called $mt\n";
323
	}
324
	
325
	/* kill any running dhcpd */
326
	if(is_process_running("dhcpd")) {
327
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
328
	}
329

    
330
	/* DHCP enabled on any interfaces? */
331
	if (!is_dhcp_server_enabled())
332
		return 0;
333

    
334
	/* if OLSRD is enabled, allow WAN to house DHCP. */
335
	if($config['installedpackages']['olsrd'])
336
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
337
				if($olsrd['enable'])
338
					$is_olsr_enabled = true;
339

    
340
	if ($g['booting']) {
341
		if ($g['platform'] != "pfSense") {
342
			/* restore the leases, if we have them */
343
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
344
				$dhcprestore = "";
345
				$dhcpreturn = "";
346
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
347
				$dhcprestore = implode(" ", $dhcprestore);
348
				if($dhcpreturn <> 0) {
349
					log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n"));
350
				}
351
			}
352
		}
353
	}
354

    
355
	$syscfg = $config['system'];
356
	if (!is_array($config['dhcpd']))
357
		$config['dhcpd'] = array();
358
	$dhcpdcfg = $config['dhcpd'];
359
	$Iflist = get_configured_interface_list();
360
		
361
	if ($g['booting'])
362
		echo gettext("Starting DHCP service...");
363
	else
364
		sleep(1);
365

    
366
	/* write dhcpd.conf */
367
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
368
	if (!$fd) {
369
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
370
		return 1;
371
	}
372

    
373
	$custoptions = "";
374
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
375
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
376
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
377
				if(!empty($item['type']))
378
					$itemtype = $item['type'];
379
				else
380
					$itemtype = "text";
381
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
382
			}
383
		}
384
	}
385

    
386
	$dhcpdconf = <<<EOD
387
	
388
option domain-name "{$syscfg['domain']}";
389
option ldap-server code 95 = text;
390
option domain-search-list code 119 = text;
391
{$custoptions}
392
default-lease-time 7200;
393
max-lease-time 86400;
394
log-facility local7;
395
ddns-update-style none;
396
one-lease-per-client true;
397
deny duplicates;
398
ping-check true;
399

    
400
EOD;
401

    
402
	if(!isset($dhcpifconf['disableauthoritative']))
403
		$dhcpdconf .= "authoritative;\n";
404

    
405
	if(isset($dhcpifconf['alwaysbroadcast'])) 
406
		$dhcpdconf .= "always-broadcast on\n";
407

    
408
	$dhcpdifs = array();
409

    
410
	/*    loop through and determine if we need to setup
411
	 *    failover peer "bleh" entries
412
	 */
413
	$dhcpnum = 0;
414
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
415

    
416
		interfaces_staticarp_configure($dhcpif);
417

    
418
		if (!isset($dhcpifconf['enable']))
419
			continue;
420

    
421
		if($dhcpifconf['failover_peerip'] <> "") {
422
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
423
			$intip = find_interface_ip($int);
424
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
425
			/*
426
			 *    yep, failover peer is defined.
427
			 *    does it match up to a defined vip?
428
			 */
429
			$skew = 110;
430
			$a_vip = &$config['virtualip']['vip'];
431
			if(is_array($a_vip)) {
432
				foreach ($a_vip as $vipent) {
433
					if($int == $real_dhcpif) {
434
						/* this is the interface! */
435
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
436
							$skew = 0;
437
					}
438
				}
439
			} else {
440
				log_error(gettext("Warning!  DHCP Failover setup and no CARP virtual IP's defined!"));
441
			}
442
			if($skew > 10) {
443
				$type = "secondary";
444
				$dhcpdconf_pri  = "mclt 600;\n";
445
				$my_port = "520";
446
				$peer_port = "519";
447
			} else {
448
				$my_port = "519";
449
				$peer_port = "520";
450
				$type = "primary";
451
				$dhcpdconf_pri  = "split 128;\n";
452
				$dhcpdconf_pri .= "  mclt 600;\n";
453
			}
454
			$dhcpdconf .= <<<EOPP
455
failover peer "dhcp{$dhcpnum}" {
456
  {$type};
457
  address {$intip};
458
  port {$my_port};
459
  peer address {$dhcpifconf['failover_peerip']};
460
  peer port {$peer_port};
461
  max-response-delay 10;
462
  max-unacked-updates 10;
463
  {$dhcpdconf_pri}
464
  load balance max seconds 3;
465
}
466

    
467
EOPP;
468
		$dhcpnum++;
469
		}
470
	}
471

    
472
	$dhcpnum = 0;
473

    
474
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
475

    
476
		$ifcfg = $config['interfaces'][$dhcpif];
477

    
478
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
479
			continue;
480
		$ifcfgip = get_interface_ip($dhcpif);
481
		$ifcfgsn = get_interface_subnet($dhcpif);
482
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
483
		$subnetmask = gen_subnet_mask($ifcfgsn);
484

    
485
		if (!is_ipaddr($subnet))
486
			continue;
487

    
488
		if($is_olsr_enabled == true)
489
			if($dhcpifconf['netmask'])
490
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
491

    
492
		$dnscfg = "";
493

    
494
		if ($dhcpifconf['domain']) {
495
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
496
		}
497
		
498
    		if($dhcpifconf['domainsearchlist'] <> "") {
499
			$dnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpifconf['domainsearchlist'])) . "\";\n";
500
    		}
501

    
502
		if (isset($dhcpifconf['ddnsupdate'])) {
503
			if($dhcpifconf['ddnsdomain'] <> "") {
504
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
505
			}
506
			$dnscfg .= "	ddns-update-style interim;\n";
507
		}
508

    
509
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
510
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
511
		} else if (isset($config['dnsmasq']['enable'])) {
512
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
513
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
514
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
515
		}
516

    
517
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
518
		$dhcpdconf .= "	pool {\n";
519

    
520
		/* is failover dns setup? */
521
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
522
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
523
			if($dhcpifconf['dnsserver'][1] <> "")
524
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
525
			$dhcpdconf .= ";\n";
526
		}
527

    
528
		if($dhcpifconf['failover_peerip'] <> "")
529
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
530

    
531
		if (isset($dhcpifconf['denyunknown']))
532
		   $dhcpdconf .= "		deny unknown-clients;\n";
533

    
534
		if ($dhcpifconf['gateway'])
535
			$routers = $dhcpifconf['gateway'];
536
		else
537
			$routers = $ifcfgip;
538

    
539
		if($dhcpifconf['failover_peerip'] <> "") {
540
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
541
			$dhcpnum++;
542
		}
543

    
544
		$dhcpdconf .= <<<EOD
545
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
546
	}
547
	option routers {$routers};
548
$dnscfg
549

    
550
EOD;
551
    		// default-lease-time
552
		if ($dhcpifconf['defaultleasetime'])
553
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
554

    
555
		// max-lease-time
556
		if ($dhcpifconf['maxleasetime'])
557
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
558

    
559
		// netbios-name*
560
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
561
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
562
			$dhcpdconf .= "	option netbios-node-type 8;\n";
563
		}
564

    
565
		// ntp-servers
566
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
567
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
568

    
569
		// tftp-server-name
570
		if ($dhcpifconf['tftp'] <> "")
571
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
572

    
573
		// Handle option, number rowhelper values
574
		$dhcpdconf .= "\n";
575
		if($dhcpifconf['numberoptions']['item']) {
576
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
577
				if(empty($item['type']) || $item['type'] == "text")
578
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
579
				else
580
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
581
			}
582
		}
583

    
584
		// ldap-server
585
		if ($dhcpifconf['ldap'] <> "")
586
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
587

    
588
		// net boot information
589
		if(isset($dhcpifconf['netboot'])) {
590
			if ($dhcpifconf['nextserver'] <> "") {
591
				$dhcpdconf .= "	next-server {$dhcpifconf['nextserver']};\n";
592
			}
593
			if ($dhcpifconf['filename'] <> "") {
594
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
595
			}
596
			if ($dhcpifconf['rootpath'] <> "") {
597
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
598
      		}
599
		}
600
		
601
		$dhcpdconf .= <<<EOD
602
}
603

    
604
EOD;
605

    
606
		/* add static mappings */
607
		if (is_array($dhcpifconf['staticmap'])) {
608

    
609
			$i = 0;
610
			foreach ($dhcpifconf['staticmap'] as $sm) {
611
				$dhcpdconf .= <<<EOD
612
host s_{$dhcpif}_{$i} {
613
	hardware ethernet {$sm['mac']};
614

    
615
EOD;
616
				if ($sm['ipaddr'])
617
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
618

    
619
				if ($sm['hostname']) {
620
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
621
					$dhhostname = str_replace(".", "_", $dhhostname);
622
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
623
				}
624
				if ($sm['filename'])
625
					$dhcpdconf .= "	filename \"{$sm['filename']}\";\n";
626

    
627
				if ($sm['rootpath'])
628
					$dhcpdconf .= "	option root-path \"{$sm['rootpath']}\";\n";
629

    
630
				$dhcpdconf .= "}\n";
631
				$i++;
632
			}
633
		}
634

    
635
		$dhcpdifs[] = get_real_interface($dhcpif);
636
	}
637

    
638
	fwrite($fd, $dhcpdconf);
639
	fclose($fd);
640

    
641
	/* create an empty leases database */
642
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
643
	
644

    
645
	/* fire up dhcpd in a chroot */
646
	if(count($dhcpdifs) > 0) {
647
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
648
			join(" ", $dhcpdifs));
649
	}
650

    
651
	if ($g['booting']) {
652
		print "done.\n";
653
	}
654

    
655
	return 0;
656
}
657

    
658
function services_dhcpdv6_configure() {
659
	global $config, $g;
660
	
661
	if($g['services_dhcp_server_enable'] == false) 
662
		return;
663

    
664
	if(isset($config['system']['developerspew'])) {
665
		$mt = microtime();
666
		echo "services_dhcpd_configure($if) being called $mt\n";
667
	}
668
	
669
	/* kill any running dhcpd */
670
	if(is_process_running("dhcpd")) {
671
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
672
	}
673

    
674
	/* DHCP enabled on any interfaces? */
675
	if (!is_dhcp_server_enabled())
676
		return 0;
677

    
678
	/* if OLSRD is enabled, allow WAN to house DHCP. */
679
	if($config['installedpackages']['olsrd'])
680
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
681
				if($olsrd['enable'])
682
					$is_olsr_enabled = true;
683

    
684
	if ($g['booting']) {
685
		if ($g['platform'] != "pfSense") {
686
			/* restore the leases, if we have them */
687
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
688
				$dhcprestore = "";
689
				$dhcpreturn = "";
690
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
691
				$dhcprestore = implode(" ", $dhcprestore);
692
				if($dhcpreturn <> 0) {
693
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
694
				}
695
			}
696
		}
697
	}
698

    
699
	$syscfg = $config['system'];
700
	if (!is_array($config['dhcpdv6']))
701
		$config['dhcpdv6'] = array();
702
	$dhcpdv6cfg = $config['dhcpdv6'];
703
	$Iflist = get_configured_interface_list();
704
		
705
	if ($g['booting'])
706
		echo "Starting DHCPv6 service...";
707
	else
708
		sleep(1);
709

    
710
	/* write dhcpdv6.conf */
711
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
712
	if (! $fdv6) {
713
		printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n");
714
		return 1;
715
	}
716

    
717
	$custoptionsv6 = "";
718
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {	
719
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
720
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
721
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
722
			}
723
		}
724
	}
725

    
726
	$dhcpdv6conf = <<<EOD
727
	
728
option domain-name "{$syscfg['domain']}";
729
option ldap-server code 95 = text;
730
option domain-search-list code 119 = text;
731
{$custoptions}
732
default-lease-time 7200;
733
max-lease-time 86400;
734
log-facility local7;
735
ddns-update-style none;
736
one-lease-per-client true;
737
deny duplicates;
738
ping-check true;
739

    
740
EOD;
741

    
742
	if(!isset($dhcpv6ifconf['disableauthoritative']))
743
		$dhcpdv6conf .= "authoritative;\n";
744

    
745
	if(isset($dhcpv6ifconf['alwaysbroadcast'])) 
746
		$dhcpdv6conf .= "always-broadcast on\n";
747

    
748
	$dhcpdv6ifs = array();
749

    
750
	/*    loop through and determine if we need to setup
751
	 *    failover peer "bleh" entries
752
	 */
753
	$dhcpv6num = 0;
754
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
755

    
756
		if (!isset($dhcpv6ifconf['enable']))
757
			continue;
758

    
759
		if($dhcpv6ifconf['failover_peerip'] <> "") {
760
			$intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']);
761
			$intipv6 = find_interface_ipv6($intv6);
762
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
763
			/*
764
			 *    yep, failover peer is defined.
765
			 *    does it match up to a defined vip?
766
			 */
767
			$skew = 110;
768
			$a_vip = &$config['virtualip']['vip'];
769
			if(is_array($a_vip)) {
770
				foreach ($a_vip as $vipent) {
771
					if($intv6 == $real_dhcpv6if) {
772
						/* this is the interface! */
773
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
774
							$skew = 0;
775
					}
776
				}
777
			} else {
778
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
779
			}
780
			if($skew > 10) {
781
				$typev6 = "secondary";
782
				$dhcpdv6conf_pri  = "mclt 600;\n";
783
				$my_portv6 = "520";
784
				$peer_portv6 = "519";
785
			} else {
786
				$my_portv6 = "519";
787
				$peer_portv6 = "520";
788
				$typev6 = "primary";
789
				$dhcpdv6conf_pri  = "split 128;\n";
790
				$dhcpdv6conf_pri .= "  mclt 600;\n";
791
			}
792
			$dhcpdv6conf .= <<<EOPP
793
failover peer "dhcpv6{$dhcpv6num}" {
794
  {$typev6};
795
  address {$intipv6};
796
  port {$my_portv6};
797
  peer address {$dhcpv6ifconf['failover_peerip']};
798
  peer port {$peer_portv6};
799
  max-response-delay 10;
800
  max-unacked-updates 10;
801
  {$dhcpdv6conf_pri}
802
  load balance max seconds 3;
803
}
804

    
805
EOPP;
806
		$dhcpv6num++;
807
		}
808
	}
809

    
810
	$dhcpv6num = 0;
811
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
812

    
813
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
814

    
815
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
816
			continue;
817
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
818
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
819
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
820
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
821

    
822
		if($is_olsr_enabled == true)
823
			if($dhcpv6ifconf['netmask'])
824
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
825

    
826
		$dnscfgv6 = "";
827

    
828
		if ($dhcpv6ifconf['domain']) {
829
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
830
		}
831
		
832
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
833
			$dnscfgv6 .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpv6ifconf['domainsearchlist'])) . "\";\n";
834
    		}
835

    
836
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
837
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
838
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
839
			}
840
			$dnscfgv6 .= "	ddns-update-style interim;\n";
841
		}
842

    
843
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
844
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
845
		} else if (isset($config['dnsmasq']['enable'])) {
846
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
847
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
848
			$dns_arrv6 = array();
849
			foreach($syscfg['dnsserver'] as $dnsserver) {
850
				if(is_ipaddrv6($dnsserver)) {
851
					$dns_arrv6[] = $dnsserver;
852
				}
853
			}
854
			if(!empty($dns_arrv6))
855
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
856
		}
857

    
858
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
859
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
860

    
861
		/* is failover dns setup? */
862
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
863
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
864
			if($dhcpv6ifconf['dnsserver'][1] <> "")
865
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
866
			$dhcpdv6conf .= ";\n";
867
		}
868

    
869
		if($dhcpv6ifconf['failover_peerip'] <> "")
870
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
871

    
872
		if (isset($dhcpv6ifconf['denyunknown']))
873
		   $dhcpdv6conf .= "		deny unknown-clients;\n";
874

    
875
		if ($dhcpv6ifconf['gateway'])
876
			$routersv6 = $dhcpv6ifconf['gateway'];
877
		else
878
			$routersv6 = $ifcfgipv6;
879

    
880
		if($dhcpv6ifconf['failover_peerip'] <> "") {
881
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
882
			$dhcpv6num++;
883
		}
884

    
885
		$dhcpdv6conf .= <<<EOD
886
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
887
	# Not supported in IPv6; option dhcp6.routers {$routersv6};
888
$dnscfgv6
889

    
890
EOD;
891

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

    
895
		}
896
    		// default-lease-time
897
		if ($dhcpv6ifconf['defaultleasetime'])
898
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
899

    
900
		// max-lease-time
901
		if ($dhcpv6ifconf['maxleasetime'])
902
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
903

    
904
		// ntp-servers
905
		/* Not supported in ISC DHCPD yet, see redmine #2016
906
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0])
907
			$dhcpdv6conf .= "	option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
908
		*/
909

    
910
		// tftp-server-name
911
		/* Needs ISC DHCPD support
912
		 if ($dhcpv6ifconf['tftp'] <> "")
913
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
914
		*/
915

    
916
		// Handle option, number rowhelper values
917
		$dhcpdv6conf .= "\n";
918
		if($dhcpv6ifconf['numberoptions']['item']) {
919
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
920
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
921
			}
922
		}
923

    
924
		// ldap-server
925
		if ($dhcpv6ifconf['ldap'] <> "")
926
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
927

    
928
		// net boot information
929
		if(isset($dhcpv6ifconf['netboot'])) {
930
			if ($dhcpv6ifconf['nextserver'] <> "") {
931
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['nextserver']};\n";
932
			}
933
			if ($dhcpv6ifconf['filename'] <> "") {
934
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
935
			}
936
			if ($dhcpv6ifconf['rootpath'] <> "") {
937
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
938
      		}
939
	}
940
		
941
		$dhcpdv6conf .= <<<EOD
942
}
943

    
944
EOD;
945

    
946
		/* add static mappings */
947
		/* Needs to use DUID */
948
		if (is_array($dhcpv6ifconf['staticmap'])) {
949

    
950
			$i = 0;
951
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
952
				$dhcpdv6conf .= <<<EOD
953
host s_{$dhcpv6if}_{$i} {
954
	host-identifier option dhcp6.client-id {$sm['duid']};
955

    
956
EOD;
957
				if ($sm['ipaddrv6'])
958
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
959

    
960
				if ($sm['hostname']) {
961
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
962
					$dhhostname = str_replace(".", "_", $dhhostname);
963
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
964
				}
965
				if ($sm['filename'])
966
					$dhcpdv6conf .= "	filename \"{$sm['filename']}\";\n";
967

    
968
				if ($sm['rootpath'])
969
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
970

    
971
				$dhcpdv6conf .= "}\n";
972
				$i++;
973
			}
974
		}
975
		
976
		if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") {
977
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
978
			$dhcpdv6ifs[] = $realif;
979
			exec("/sbin/ifconfig {$realif} |awk  '/ether/ {print $2}'", $mac);
980
			$v6address = generate_ipv6_from_mac($mac[0]);
981
			/* Create link local address for bridges */
982
			if(stristr("$realif", "bridge")) {
983
				mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
984
			}
985
		}
986
	}
987

    
988
	fwrite($fdv6, $dhcpdv6conf);
989
	fclose($fdv6);
990
	/* create an empty leases v6 database */
991
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
992
	
993

    
994
	/* fire up dhcpd in a chroot */
995
	if(count($dhcpdv6ifs) > 0) {
996
		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 " .
997
			join(" ", $dhcpdv6ifs));
998
	}
999

    
1000
	if ($g['booting']) {
1001
		print gettext("done.") . "\n";
1002
	}
1003

    
1004
	return 0;
1005
}
1006

    
1007
function services_igmpproxy_configure() {
1008
        global $config, $g;
1009

    
1010
        /* kill any running igmpproxy */
1011
        killbyname("igmpproxy");
1012

    
1013
	if (!is_array($config['igmpproxy']['igmpentry']))
1014
		return 1;
1015

    
1016
        $iflist = get_configured_interface_list();
1017

    
1018
        $igmpconf = <<<EOD
1019

    
1020
##------------------------------------------------------
1021
## Enable Quickleave mode (Sends Leave instantly)
1022
##------------------------------------------------------
1023
quickleave
1024

    
1025
EOD;
1026

    
1027
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
1028
                unset($iflist[$igmpcf['ifname']]);
1029
                $realif = get_real_interface($igmpcf['ifname']);
1030
                if (empty($igmpcf['threshold']))
1031
                        $threshld = 1;
1032
                else
1033
                        $threshld = $igmpcf['threshold'];
1034
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
1035

    
1036
                if ($igmpcf['address'] <> "") {
1037
                        $item = explode(" ", $igmpcf['address']);
1038
                        foreach($item as $iww)
1039
                                $igmpconf .= "altnet {$iww}\n";
1040
                }
1041
                $igmpconf .= "\n";
1042
        }
1043
        foreach ($iflist as $ifn) {
1044
                $realif = get_real_interface($ifn);
1045
                $igmpconf .= "phyint {$realif} disabled\n";
1046
        }
1047
	$igmpconf .= "\n";
1048

    
1049
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
1050
        if (!$igmpfl) {
1051
                log_error(gettext("Could not write Igmpproxy configuration file!"));
1052
                return;
1053
        }
1054
        fwrite($igmpfl, $igmpconf);
1055
        fclose($igmpfl);
1056

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

    
1060
        return 0;
1061
}
1062

    
1063
function services_dhcrelay_configure() {
1064
	global $config, $g;
1065
	if ($g['platform'] == 'jail')
1066
		return;
1067
	if(isset($config['system']['developerspew'])) {
1068
		$mt = microtime();
1069
		echo "services_dhcrelay_configure() being called $mt\n";
1070
	}
1071

    
1072
	/* kill any running dhcrelay */
1073
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1074

    
1075
	$dhcrelaycfg =& $config['dhcrelay'];
1076

    
1077
	/* DHCPRelay enabled on any interfaces? */
1078
	if (!isset($dhcrelaycfg['enable']))
1079
		return 0;
1080

    
1081
	if ($g['booting'])
1082
		echo gettext("Starting DHCP relay service...");
1083
	else
1084
		sleep(1);
1085

    
1086
	$iflist = get_configured_interface_list();
1087

    
1088
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1089
	foreach ($dhcifaces as $dhcrelayif) {
1090
		if (!isset($iflist[$dhcrelayif]) ||
1091
			link_interface_to_bridge($dhcrelayif))
1092
			continue;
1093

    
1094
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
1095
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1096
	}
1097

    
1098
	/* 
1099
	 * In order for the relay to work, it needs to be active
1100
	 * on the interface in which the destination server sits.
1101
	 */
1102
	$srvips = explode(",", $dhcrelaycfg['server']);
1103
	foreach ($srvips as $srcidx => $srvip) {
1104
		unset($destif);
1105
		foreach ($iflist as $ifname) {
1106
			$subnet = get_interface_ip($ifname);
1107
			if (!is_ipaddr($subnet))
1108
				continue;
1109
			$subnet .=  "/" . get_interface_subnet($ifname);
1110
			if (ip_in_subnet($srvip, $subnet)) {
1111
				$destif = get_real_interface($ifname);
1112
				break;
1113
			}
1114
		}
1115
		if (!isset($destif)) {
1116
			if (is_array($config['staticroutes']['route'])) {
1117
				foreach ($config['staticroutes']['route'] as $rtent) {
1118
					if (ip_in_subnet($srvip, $rtent['network'])) {
1119
						$a_gateways = return_gateways_array(true);
1120
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1121
						break;
1122
					}
1123
				}
1124
			}
1125
		}
1126

    
1127
		if (!isset($destif)) {
1128
			/* Create a array from the existing route table */
1129
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
1130
        		array_shift($route_str);
1131
        		array_shift($route_str);
1132
        		array_shift($route_str);
1133
        		array_shift($route_str);
1134
        		$route_arr = array();
1135
        		foreach($route_str as $routeline) {
1136
                		$items = preg_split("/[ ]+/i", $routeline);
1137
				if (ip_in_subnet($srvip, $items[0])) {
1138
					$destif = trim($items[6]);
1139
					break;
1140
				}
1141
        		}
1142
		}
1143
	
1144
		if (!isset($destif)) {
1145
			if (is_array($config['gateways']['gateway_item'])) {
1146
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1147
					if (isset($gateway['defaultgw'])) {
1148
						$a_gateways = return_gateways_array(true);
1149
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1150
						break;
1151
					}		
1152
				}
1153
			} else
1154
				$destif = get_real_interface("wan");
1155
		}
1156

    
1157
		if (!empty($destif))
1158
			$dhcrelayifs[] = $destif;
1159
	}
1160
	$dhcrelayifs = array_unique($dhcrelayifs);
1161

    
1162
	/* fire up dhcrelay */
1163
	if (empty($dhcrelayifs)) {
1164
		log_error("No suitable interface found for running dhcrelay!");
1165
		return; /* XXX */
1166
	}
1167

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

    
1170
	if (isset($dhcrelaycfg['agentoption']))
1171
		$cmd .=  " -a -m replace";
1172

    
1173
	$cmd .= " " . implode(" ", $srvips);
1174
	mwexec($cmd);
1175

    
1176
	return 0;
1177
}
1178

    
1179
function services_dhcrelay6_configure() {
1180
	global $config, $g;
1181
	if ($g['platform'] == 'jail')
1182
		return;
1183
	if(isset($config['system']['developerspew'])) {
1184
		$mt = microtime();
1185
		echo "services_dhcrelay_configure() being called $mt\n";
1186
	}
1187

    
1188
	/* kill any running dhcrelay */
1189
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1190

    
1191
	$dhcrelaycfg =& $config['dhcrelay6'];
1192

    
1193
	/* DHCPv6 Relay enabled on any interfaces? */
1194
	if (!isset($dhcrelaycfg['enable']))
1195
		return 0;
1196

    
1197
	if ($g['booting'])
1198
		echo gettext("Starting DHCPv6 relay service...");
1199
	else
1200
		sleep(1);
1201

    
1202
	$iflist = get_configured_interface_list();
1203

    
1204
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1205
	foreach ($dhcifaces as $dhcrelayif) {
1206
		if (!isset($iflist[$dhcrelayif]) ||
1207
			link_interface_to_bridge($dhcrelayif))
1208
			continue;
1209

    
1210
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif)))
1211
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1212
	}
1213

    
1214
	/* 
1215
	 * In order for the relay to work, it needs to be active
1216
	 * on the interface in which the destination server sits.
1217
	 */
1218
	$srvips = explode(",", $dhcrelaycfg['server']);
1219
	foreach ($srvips as $srcidx => $srvip) {
1220
		unset($destif);
1221
		foreach ($iflist as $ifname) {
1222
			$subnet = get_interface_ipv6($ifname);
1223
			if (!is_ipaddrv6($subnet))
1224
				continue;
1225
			$subnet .=  "/" . get_interface_subnetv6($ifname);
1226
			if (ip_in_subnet($srvip, $subnet)) {
1227
				$destif = get_real_interface($ifname);
1228
				break;
1229
			}
1230
		}
1231
		if (!isset($destif)) {
1232
			if (is_array($config['staticroutes']['route'])) {
1233
				foreach ($config['staticroutes']['route'] as $rtent) {
1234
					if (ip_in_subnet($srvip, $rtent['network'])) {
1235
						$a_gateways = return_gateways_array(true);
1236
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1237
						break;
1238
					}
1239
				}
1240
			}
1241
		}
1242

    
1243
		if (!isset($destif)) {
1244
			/* Create a array from the existing route table */
1245
        		exec("/usr/bin/netstat -rnWf inet6", $route_str);
1246
        		array_shift($route_str);
1247
        		array_shift($route_str);
1248
        		array_shift($route_str);
1249
        		array_shift($route_str);
1250
        		$route_arr = array();
1251
        		foreach($route_str as $routeline) {
1252
                		$items = preg_split("/[ ]+/i", $routeline);
1253
				if (ip_in_subnet($srvip, $items[0])) {
1254
					$destif = trim($items[6]);
1255
					break;
1256
				}
1257
        		}
1258
		}
1259
	
1260
		if (!isset($destif)) {
1261
			if (is_array($config['gateways']['gateway_item'])) {
1262
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1263
					if (isset($gateway['defaultgw'])) {
1264
						$a_gateways = return_gateways_array(true);
1265
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1266
						break;
1267
					}		
1268
				}
1269
			} else
1270
				$destif = get_real_interface("wan");
1271
		}
1272

    
1273
		if (!empty($destif))
1274
			$dhcrelayifs[] = $destif;
1275
	}
1276
	$dhcrelayifs = array_unique($dhcrelayifs);
1277

    
1278
	/* fire up dhcrelay */
1279
	if (empty($dhcrelayifs)) {
1280
		log_error("No suitable interface found for running dhcrelay -6!");
1281
		return; /* XXX */
1282
	}
1283

    
1284
	$cmd = "/usr/local/sbin/dhcrelay -6 -pf \"{$g['varetc_path']}/dhcrelay6.pid\" -i " .  implode(" -i ", $dhcrelayifs);
1285

    
1286
	if (isset($dhcrelaycfg['agentoption']))
1287
		$cmd .=  " -a -m replace";
1288

    
1289
	$cmd .= " " . implode(" ", $srvips);
1290
	mwexec($cmd);
1291

    
1292
	return 0;
1293
}
1294

    
1295
function services_dyndns_configure_client($conf) {
1296

    
1297
	if (!isset($conf['enable']))
1298
		return;
1299

    
1300
	/* load up the dyndns.class */
1301
	require_once("dyndns.class");
1302

    
1303
	$dns = new updatedns($dnsService = $conf['type'],
1304
		$dnsHost = $conf['host'],
1305
		$dnsUser = $conf['username'],
1306
		$dnsPass = $conf['password'],
1307
		$dnsWilcard = $conf['wildcard'],
1308
		$dnsMX = $conf['mx'], 
1309
		$dnsIf = "{$conf['interface']}",
1310
		$dnsBackMX = NULL,
1311
		$dnsServer = NULL,
1312
		$dnsPort = NULL,
1313
		$dnsUpdateURL = NULL,
1314
		$forceUpdate = $conf['force']);
1315
}
1316

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

    
1324
	$dyndnscfg = $config['dyndnses']['dyndns'];
1325

    
1326
	if (is_array($dyndnscfg)) {
1327
		if ($g['booting']) 
1328
			echo gettext("Starting DynDNS clients...");
1329

    
1330
		foreach ($dyndnscfg as $dyndns) {
1331
			if (!empty($int) && $int != $dyndns['interface'])
1332
				continue;
1333

    
1334
			services_dyndns_configure_client($dyndns);
1335

    
1336
			sleep(1);
1337
		}
1338

    
1339
		if ($g['booting'])
1340
			echo gettext("done.") . "\n";
1341
	}
1342

    
1343
	return 0;
1344
}
1345

    
1346
function services_dnsmasq_configure() {
1347
	global $config, $g;
1348
	$return = 0;
1349
	
1350
	if(isset($config['system']['developerspew'])) {
1351
		$mt = microtime();
1352
		echo "services_dnsmasq_configure() being called $mt\n";
1353
	}
1354

    
1355
	/* kill any running dnsmasq */
1356
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
1357
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1358

    
1359
	if (isset($config['dnsmasq']['enable'])) {
1360

    
1361
		if ($g['booting'])
1362
			echo gettext("Starting DNS forwarder...");
1363
		else
1364
			sleep(1);
1365

    
1366
		/* generate hosts file */
1367
		if(system_hosts_generate()!=0)
1368
			$return = 1;
1369

    
1370
		$args = "";
1371

    
1372
		if (isset($config['dnsmasq']['regdhcp'])) {
1373
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1374
		}
1375
		
1376
		/* Setup forwarded domains */
1377
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1378
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1379
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1380
			}
1381
		}
1382

    
1383
		/* Allow DNS Rebind for forwarded domains */
1384
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1385
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1386
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1387
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1388
				}
1389
			}
1390
		}
1391

    
1392
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1393
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1394

    
1395
		if ($config['dnsmasq']['custom_options']) {
1396
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1397
				$args .= " --$c";
1398
		}
1399

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

    
1403
		if ($g['booting'])
1404
			echo gettext("done.") . "\n";
1405
	}
1406

    
1407
	if (!$g['booting']) {
1408
		if(services_dhcpd_configure()!=0)
1409
			$return = 1;
1410
	}
1411

    
1412
	return $return;
1413
}
1414

    
1415
function services_unbound_configure() {
1416
	global $config, $g;
1417
	$return = 0;
1418

    
1419
	if(isset($config['system']['developerspew'])) {
1420
		$mt = microtime();
1421
		echo "services_unbound_configure() being called $mt\n";
1422
	}
1423

    
1424
	/* kill any running unbound */
1425
	sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1426

    
1427
	if (isset($config['unbound']['enable'])) {
1428

    
1429
		if ($g['booting'])
1430
			echo "Starting Unbound DNS...";
1431
		else
1432
			sleep(1);
1433

    
1434
		/* generate Unbound config file */
1435
		if(unbound_generate_config()!=0) {
1436
			log_error("Problem generating Unbound configuration.");
1437
			$return = 1;
1438
		}
1439

    
1440
		/* run Unbound */
1441
		mwexec("/usr/local/sbin/unbound");
1442

    
1443
		if ($g['booting'])
1444
			echo "done.\n";
1445
	}
1446

    
1447
	return $return;
1448
}
1449

    
1450
function services_snmpd_configure() {
1451
	global $config, $g;
1452
	if(isset($config['system']['developerspew'])) {
1453
		$mt = microtime();
1454
		echo "services_snmpd_configure() being called $mt\n";
1455
	}
1456

    
1457
	/* kill any running snmpd */
1458
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1459
	sleep(2);
1460
	if(is_process_running("bsnmpd")) 
1461
		mwexec("/usr/bin/killall bsnmpd", true);
1462

    
1463
	if (isset($config['snmpd']['enable'])) {
1464

    
1465
		if ($g['booting'])
1466
			echo gettext("Starting SNMP daemon... ");
1467

    
1468
		/* generate snmpd.conf */
1469
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1470
		if (!$fd) {
1471
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1472
			return 1;
1473
		}
1474

    
1475

    
1476
		$snmpdconf = <<<EOD
1477
location := "{$config['snmpd']['syslocation']}"
1478
contact := "{$config['snmpd']['syscontact']}"
1479
read := "{$config['snmpd']['rocommunity']}"
1480

    
1481
EOD;
1482

    
1483
/* No docs on what write strings do there for disable for now.
1484
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1485
		    $snmpdconf .= <<<EOD
1486
# write string
1487
write := "{$config['snmpd']['rwcommunity']}"
1488

    
1489
EOD;
1490
		}
1491
*/
1492

    
1493

    
1494
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1495
		    $snmpdconf .= <<<EOD
1496
# SNMP Trap support.
1497
traphost := {$config['snmpd']['trapserver']}
1498
trapport := {$config['snmpd']['trapserverport']}
1499
trap := "{$config['snmpd']['trapstring']}"
1500

    
1501

    
1502
EOD;
1503
		}
1504

    
1505

    
1506
		$snmpdconf .= <<<EOD
1507
system := 1     # pfSense
1508
%snmpd
1509
begemotSnmpdDebugDumpPdus       = 2
1510
begemotSnmpdDebugSyslogPri      = 7
1511
begemotSnmpdCommunityString.0.1 = $(read)
1512

    
1513
EOD;
1514

    
1515
/* No docs on what write strings do there for disable for now.
1516
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1517
		    $snmpdconf .= <<<EOD
1518
begemotSnmpdCommunityString.0.2 = $(write)
1519

    
1520
EOD;
1521
		}
1522
*/
1523

    
1524

    
1525
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1526
		    $snmpdconf .= <<<EOD
1527
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1528
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1529
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1530

    
1531
EOD;
1532
		}
1533

    
1534

    
1535
		$snmpdconf .= <<<EOD
1536
begemotSnmpdCommunityDisable    = 1
1537

    
1538
EOD;
1539

    
1540
		if (isset($config['snmpd']['bindlan'])) {
1541
			$config['snmpd']['bindip'] = 'lan';
1542
			unset($config['snmpd']['bindlan']);
1543
		}
1544
		$bind_to_ip = "0.0.0.0";
1545
		if(isset($config['snmpd']['bindip'])) {
1546
			if (is_ipaddr($config['snmpd']['bindip'])) {
1547
				$bind_to_ip = $config['snmpd']['bindip'];
1548
			} else {
1549
				$if = get_real_interface($config['snmpd']['bindip']);
1550
				if (does_interface_exist($if))
1551
					$bind_to_ip = find_interface_ip($if);
1552
			}
1553
		}
1554

    
1555
		if(is_port( $config['snmpd']['pollport'] )) {
1556
		    $snmpdconf .= <<<EOD
1557
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1558

    
1559
EOD;
1560

    
1561
		}
1562

    
1563
		$snmpdconf .= <<<EOD
1564
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1565
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1566

    
1567
# These are bsnmp macros not php vars.
1568
sysContact      = $(contact)
1569
sysLocation     = $(location)
1570
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1571

    
1572
snmpEnableAuthenTraps = 2
1573

    
1574
EOD;
1575

    
1576
		if (is_array( $config['snmpd']['modules'] )) {
1577
		    if(isset($config['snmpd']['modules']['mibii'])) {
1578
			$snmpdconf .= <<<EOD
1579
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1580

    
1581
EOD;
1582
		    }
1583

    
1584
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1585
			$snmpdconf .= <<<EOD
1586
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1587
%netgraph
1588
begemotNgControlNodeName = "snmpd"
1589

    
1590
EOD;
1591
		    }
1592

    
1593
		    if(isset($config['snmpd']['modules']['pf'])) {
1594
			$snmpdconf .= <<<EOD
1595
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1596

    
1597
EOD;
1598
		    }
1599

    
1600
		    if(isset($config['snmpd']['modules']['hostres'])) {
1601
			$snmpdconf .= <<<EOD
1602
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1603

    
1604
EOD;
1605
		    }
1606
		    if(isset($config['snmpd']['modules']['bridge'])) {
1607
			$snmpdconf .= <<<EOD
1608
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1609
# config must end with blank line
1610

    
1611

    
1612
EOD;
1613
		    }
1614
		}
1615

    
1616
		fwrite($fd, $snmpdconf);
1617
		fclose($fd);
1618

    
1619
		if (isset($config['snmpd']['bindlan'])) {
1620
			$bindlan = "";
1621
		}
1622

    
1623
		/* run bsnmpd */
1624
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1625
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1626

    
1627
		if ($g['booting'])
1628
			echo gettext("done.") . "\n";
1629
	}
1630

    
1631
	return 0;
1632
}
1633

    
1634
function services_dnsupdate_process($int = "") {
1635
	global $config, $g;
1636
	if(isset($config['system']['developerspew'])) {
1637
		$mt = microtime();
1638
		echo "services_dnsupdate_process() being called $mt\n";
1639
	}
1640

    
1641
	/* Dynamic DNS updating active? */
1642
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1643
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1644
			if (!isset($dnsupdate['enable']))
1645
				continue;
1646
			if (!empty($int) && $int != $dnsupdate['interface'])
1647
				continue;
1648

    
1649
			/* determine interface name */
1650
			$if = get_real_interface($dnsupdate['interface']);
1651
			$wanip = get_interface_ip($dnsupdate['interface']);
1652
			if ($wanip) {
1653

    
1654
				$keyname = $dnsupdate['keyname'];
1655
				/* trailing dot */
1656
				if (substr($keyname, -1) != ".")
1657
					$keyname .= ".";
1658

    
1659
				$hostname = $dnsupdate['host'];
1660
				/* trailing dot */
1661
				if (substr($hostname, -1) != ".")
1662
					$hostname .= ".";
1663

    
1664
				/* write private key file
1665
				   this is dumb - public and private keys are the same for HMAC-MD5,
1666
				   but nsupdate insists on having both */
1667
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1668
				$privkey = <<<EOD
1669
Private-key-format: v1.2
1670
Algorithm: 157 (HMAC)
1671
Key: {$dnsupdate['keydata']}
1672

    
1673
EOD;
1674
				fwrite($fd, $privkey);
1675
				fclose($fd);
1676

    
1677
				/* write public key file */
1678
				if ($dnsupdate['keytype'] == "zone") {
1679
					$flags = 257;
1680
					$proto = 3;
1681
				} else if ($dnsupdate['keytype'] == "host") {
1682
					$flags = 513;
1683
					$proto = 3;
1684
				} else if ($dnsupdate['keytype'] == "user") {
1685
					$flags = 0;
1686
					$proto = 2;
1687
				}
1688

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

    
1693
				/* generate update instructions */
1694
				$upinst = "";
1695
				if (!empty($dnsupdate['server']))
1696
					$upinst .= "server {$dnsupdate['server']}\n";
1697
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1698
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1699
				$upinst .= "\n";	/* mind that trailing newline! */
1700

    
1701
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1702
				fwrite($fd, $upinst);
1703
				fclose($fd);
1704

    
1705
				/* invoke nsupdate */
1706
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1707
				if (isset($dnsupdate['usetcp']))
1708
					$cmd .= " -v";
1709
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1710
	
1711
				mwexec_bg($cmd);
1712
			}
1713
		}
1714
	}
1715

    
1716
	return 0;
1717
}
1718

    
1719
function setup_wireless_olsr() {
1720
	global $config, $g;
1721
	if ($g['platform'] == 'jail' || !$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1722
		return;
1723
	if(isset($config['system']['developerspew'])) {
1724
		$mt = microtime();
1725
		echo "setup_wireless_olsr($interface) being called $mt\n";
1726
	}
1727
	conf_mount_rw();
1728
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1729
		$olsr_enable = $olsrd['enable'];
1730
		if($olsr_enable <> "on") {
1731
			if (is_process_running("olsrd"))
1732
				mwexec("/usr/bin/killall olsrd", true);
1733
			return;
1734
		}
1735
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1736

    
1737
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1738
			$enableannounce .= "\nHna4\n";
1739
			$enableannounce .= "{\n";
1740
		if($olsrd['announcedynamicroute'])
1741
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1742
		if($olsrd['enableannounce'] == "on")
1743
			$enableannounce .= "0.0.0.0 0.0.0.0";
1744
			$enableannounce .= "\n}\n";
1745
		} else {
1746
			$enableannounce = "";
1747
		}
1748

    
1749
		$olsr .= <<<EODA
1750
#
1751
# olsr.org OLSR daemon config file
1752
#
1753
# Lines starting with a # are discarded
1754
#
1755
# This file was generated by setup_wireless_olsr() in services.inc
1756
#
1757

    
1758
# This file is an example of a typical
1759
# configuration for a mostly static
1760
# network(regarding mobility) using
1761
# the LQ extention
1762

    
1763
# Debug level(0-9)
1764
# If set to 0 the daemon runs in the background
1765

    
1766
DebugLevel	2
1767

    
1768
# IP version to use (4 or 6)
1769

    
1770
IpVersion	4
1771

    
1772
# Clear the screen each time the internal state changes
1773

    
1774
ClearScreen     yes
1775

    
1776
{$enableannounce}
1777

    
1778
# Should olsrd keep on running even if there are
1779
# no interfaces available? This is a good idea
1780
# for a PCMCIA/USB hotswap environment.
1781
# "yes" OR "no"
1782

    
1783
AllowNoInt	yes
1784

    
1785
# TOS(type of service) value for
1786
# the IP header of control traffic.
1787
# If not set it will default to 16
1788

    
1789
#TosValue	16
1790

    
1791
# The fixed willingness to use(0-7)
1792
# If not set willingness will be calculated
1793
# dynamically based on battery/power status
1794
# if such information is available
1795

    
1796
#Willingness    	4
1797

    
1798
# Allow processes like the GUI front-end
1799
# to connect to the daemon.
1800

    
1801
IpcConnect
1802
{
1803
     # Determines how many simultaneously
1804
     # IPC connections that will be allowed
1805
     # Setting this to 0 disables IPC
1806

    
1807
     MaxConnections  0
1808

    
1809
     # By default only 127.0.0.1 is allowed
1810
     # to connect. Here allowed hosts can
1811
     # be added
1812

    
1813
     Host            127.0.0.1
1814
     #Host            10.0.0.5
1815

    
1816
     # You can also specify entire net-ranges
1817
     # that are allowed to connect. Multiple
1818
     # entries are allowed
1819

    
1820
     #Net             192.168.1.0 255.255.255.0
1821
}
1822

    
1823
# Wether to use hysteresis or not
1824
# Hysteresis adds more robustness to the
1825
# link sensing but delays neighbor registration.
1826
# Used by default. 'yes' or 'no'
1827

    
1828
UseHysteresis	no
1829

    
1830
# Hysteresis parameters
1831
# Do not alter these unless you know
1832
# what you are doing!
1833
# Set to auto by default. Allowed
1834
# values are floating point values
1835
# in the interval 0,1
1836
# THR_LOW must always be lower than
1837
# THR_HIGH.
1838

    
1839
#HystScaling	0.50
1840
#HystThrHigh	0.80
1841
#HystThrLow	0.30
1842

    
1843

    
1844
# Link quality level
1845
# 0 = do not use link quality
1846
# 1 = use link quality for MPR selection
1847
# 2 = use link quality for MPR selection and routing
1848
# Defaults to 0
1849

    
1850
LinkQualityLevel	{$olsrd['enablelqe']}
1851

    
1852
# Link quality window size
1853
# Defaults to 10
1854

    
1855
LinkQualityWinSize	10
1856

    
1857
# Polling rate in seconds(float).
1858
# Default value 0.05 sec
1859

    
1860
Pollrate	0.05
1861

    
1862

    
1863
# TC redundancy
1864
# Specifies how much neighbor info should
1865
# be sent in TC messages
1866
# Possible values are:
1867
# 0 - only send MPR selectors
1868
# 1 - send MPR selectors and MPRs
1869
# 2 - send all neighbors
1870
#
1871
# defaults to 0
1872

    
1873
TcRedundancy	2
1874

    
1875
#
1876
# MPR coverage
1877
# Specifies how many MPRs a node should
1878
# try select to reach every 2 hop neighbor
1879
#
1880
# Can be set to any integer >0
1881
#
1882
# defaults to 1
1883

    
1884
MprCoverage	3
1885

    
1886
# Example plugin entry with parameters:
1887

    
1888
EODA;
1889

    
1890
if($olsrd['enablehttpinfo'] == "on") {
1891
	$olsr .= <<<EODB
1892

    
1893
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1894
{
1895
    PlParam     "port"   "{$olsrd['port']}"
1896
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1897
}
1898

    
1899
EODB;
1900

    
1901
}
1902

    
1903
if($olsrd['enabledsecure'] == "on") {
1904
	$olsr .= <<<EODC
1905

    
1906
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1907
{
1908
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1909
}
1910

    
1911
EODC;
1912

    
1913
}
1914

    
1915
if($olsrd['enabledyngw'] == "on") {
1916

    
1917
	/* unset default route, olsr auto negotiates */
1918
	mwexec("/sbin/route delete default");
1919

    
1920
	$olsr .= <<<EODE
1921

    
1922
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1923
{
1924
    # how often to look for a inet gw, in seconds
1925
    # defaults to 5 secs, if commented out
1926
    PlParam     "Interval"   "{$olsrd['polling']}"
1927

    
1928
    # if one or more IPv4 addresses are given, do a ping on these in
1929
    # descending order to validate that there is not only an entry in
1930
    # routing table, but also a real internet connection. If any of
1931
    # these addresses could be pinged successfully, the test was
1932
    # succesful, i.e. if the ping on the 1st address was successful,the
1933
    # 2nd won't be pinged
1934
    PlParam     "Ping"       "{$olsrd['ping']}"
1935
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1936
}
1937

    
1938
EODE;
1939

    
1940
}
1941

    
1942
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1943
	$interfaces = explode(',', $conf['iface_array']);
1944
	foreach($interfaces as $interface) {
1945
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1946
$olsr .= <<<EODAD
1947
Interface "{$realinterface}"
1948
{
1949

    
1950
    # Hello interval in seconds(float)
1951
    HelloInterval    2.0
1952

    
1953
    # HELLO validity time
1954
    HelloValidityTime	20.0
1955

    
1956
    # TC interval in seconds(float)
1957
    TcInterval        5.0
1958

    
1959
    # TC validity time
1960
    TcValidityTime	30.0
1961

    
1962
    # MID interval in seconds(float)
1963
    MidInterval	5.0
1964

    
1965
    # MID validity time
1966
    MidValidityTime	30.0
1967

    
1968
    # HNA interval in seconds(float)
1969
    HnaInterval	5.0
1970

    
1971
    # HNA validity time
1972
    HnaValidityTime 	30.0
1973

    
1974
    # When multiple links exist between hosts
1975
    # the weight of interface is used to determine
1976
    # the link to use. Normally the weight is
1977
    # automatically calculated by olsrd based
1978
    # on the characteristics of the interface,
1979
    # but here you can specify a fixed value.
1980
    # Olsrd will choose links with the lowest value.
1981

    
1982
    # Weight 0
1983

    
1984

    
1985
}
1986

    
1987
EODAD;
1988

    
1989
	}
1990
	break;
1991
}
1992
		fwrite($fd, $olsr);
1993
		fclose($fd);
1994
	}
1995

    
1996
	if (is_process_running("olsrd"))
1997
		mwexec("/usr/bin/killall olsrd", true);
1998

    
1999
	sleep(2);
2000

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

    
2003
	conf_mount_ro();
2004
}
2005

    
2006
/* configure cron service */
2007
function configure_cron() {
2008
	global $g, $config;
2009

    
2010
	conf_mount_rw();
2011
	/* preserve existing crontab entries */
2012
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2013
	
2014
	for ($i = 0; $i < count($crontab_contents); $i++) {
2015
		$cron_item =& $crontab_contents[$i];
2016
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
2017
			array_splice($crontab_contents, $i - 1);
2018
			break;
2019
		}
2020
	}
2021
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
2022
	
2023
	
2024
	if (is_array($config['cron']['item'])) {
2025
		$crontab_contents .= "#\n";
2026
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2027
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
2028
		$crontab_contents .= "#\n";
2029

    
2030
		foreach ($config['cron']['item'] as $item) {
2031
			$crontab_contents .= "\n{$item['minute']}\t";
2032
			$crontab_contents .= "{$item['hour']}\t";
2033
			$crontab_contents .= "{$item['mday']}\t";
2034
			$crontab_contents .= "{$item['month']}\t";
2035
			$crontab_contents .= "{$item['wday']}\t";
2036
			$crontab_contents .= "{$item['who']}\t";
2037
			$crontab_contents .= "{$item['command']}";
2038
		}
2039
    
2040
		$crontab_contents .= "\n#\n";
2041
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2042
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2043
		$crontab_contents .= "#\n\n";
2044
	}
2045
	
2046
	/* please maintain the newline at the end of file */
2047
	file_put_contents("/etc/crontab", $crontab_contents);
2048

    
2049
	/* do a HUP kill to force sync changes */
2050
	exec('/bin/pkill -HUP cron');
2051

    
2052
	conf_mount_ro();
2053
}
2054

    
2055
function upnp_action ($action) {
2056
	global $g, $config;
2057
	switch($action) {
2058
		case "start":
2059
			if (file_exists('/var/etc/miniupnpd.conf')) {
2060
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
2061
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
2062
			}
2063
			break;
2064
		case "stop":
2065
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
2066
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
2067
				mwexec('killall miniupnpd 2>/dev/null', true);
2068
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
2069
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
2070
			break;
2071
		case "restart":
2072
			upnp_action('stop');
2073
			upnp_action('start');
2074
			break;
2075
	}
2076
}
2077

    
2078
function upnp_start() {
2079
	global $config;
2080

    
2081
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2082
		return;
2083

    
2084
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2085
		echo gettext("Starting UPnP service... ");
2086
		require_once('/usr/local/pkg/miniupnpd.inc');
2087
		sync_package_miniupnpd();
2088
		echo "done.\n";
2089
	}
2090
}
2091

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

    
2095
	$is_installed = false;
2096

    
2097
	if(!$config['cron']['item'])
2098
		return;
2099

    
2100
	$x=0;
2101
	foreach($config['cron']['item'] as $item) {
2102
		if(strstr($item['command'], $command)) {
2103
			$is_installed = true;
2104
			break;
2105
		}
2106
		$x++;
2107
	}
2108

    
2109
	if($active) {
2110
		$cron_item = array();
2111
		$cron_item['minute'] = $minute;
2112
		$cron_item['hour'] = $hour;
2113
		$cron_item['mday'] = $monthday;
2114
		$cron_item['month'] = $month;
2115
		$cron_item['wday'] = $weekday;
2116
		$cron_item['who'] = $who;
2117
		$cron_item['command'] = $command;
2118
		if(!$is_installed) {
2119
			$config['cron']['item'][] = $cron_item;
2120
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
2121
		} else {
2122
			$config['cron']['item'][$x] = $cron_item;
2123
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
2124
		}
2125
	} else {
2126
		if(($is_installed == true) && ($x > 0)) {
2127
			unset($config['cron']['item'][$x]);
2128
			write_config(sprintf(gettext("Remvoed cron job for %s"), $command));
2129
		}
2130
	}
2131
	configure_cron();
2132
}
2133

    
2134
?>
(46-46/64)