Project

General

Profile

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

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

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

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

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

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

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

    
43
function strify($str) {
44
	return '"' . $str . '"';
45
};
46

    
47

    
48
/* implement ipv6 route advertising deamon */
49
function services_radvd_configure() {
50
	global $config, $g;
51
	
52
	if ($g['platform'] == 'jail') 
53
		return;
54

    
55
	if(isset($config['system']['developerspew'])) {
56
		$mt = microtime();
57
		echo "services_radvd_configure() being called $mt\n";
58
	}
59

    
60
	/* we need to shut down the radvd cleanly, it will send out the prefix
61
	 * information with a lifetime of 0 to notify clients of a (possible) new prefix */
62
	if(is_process_running("radvd")) {
63
		log_error("Shutting down Router Advertisment daemon cleanly");
64
		mwexec("killall radvd");
65
	}
66

    
67
	if (!is_array($config['dhcpdv6']))
68
		$config['dhcpdv6'] = array();
69

    
70
	$dhcpdv6cfg = $config['dhcpdv6'];
71
	$Iflist = get_configured_interface_list();
72

    
73
	/* write radvd.conf */
74
	$fd = fopen("{$g['varetc_path']}/radvd.conf", "w");
75
	if (!$fd) {
76
		printf("Error: cannot open radvd.conf in services_radvd_configure().\n");
77
		return 1;
78
	}
79

    
80
	$radvdconf = "# Automatically Generated, do not edit\n";
81

    
82
	/* Process all links which need the router advertise daemon */
83
	$radvdnum = 0;
84
	$radvdifs = array();
85

    
86
	/* handle manually configured DHCP6 server settings first */
87
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
88
		if(!isset($config['interfaces'][$dhcpv6if]['enable']))
89
			continue;
90
								
91
		/* are router advertisements enabled? */
92
		if($dhcpv6ifconf['mode'] == "disabled")
93
			continue;
94
			
95
		$realif = get_real_interface($dhcpv6if);
96

    
97
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
98
		if(!is_ipaddrv6($ifcfgipv6))
99
			continue;
100

    
101
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
102
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
103
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
104

    
105
		$radvdifs[] = $realif;
106
		
107
		$radvdconf .= "# Generated for DHCPv6 Server $dhcpv6if\n";
108
		$radvdconf .= "interface {$realif} {\n";
109
		$radvdconf .= "\tAdvSendAdvert on;\n";
110
		$radvdconf .= "\tMinRtrAdvInterval 3;\n";
111
		$radvdconf .= "\tMaxRtrAdvInterval 10;\n";
112
		$radvdconf .= "\tAdvLinkMTU 1280;\n";
113
		// $radvdconf .= "\tDeprecatePrefix on;\n";
114
		switch($dhcpv6ifconf['mode']) {
115
			case "managed":
116
				$radvdconf .= "\tAdvManagedFlag on;\n";
117
				break;
118
			case "assist":
119
				$radvdconf .= "\tAdvOtherConfigFlag on;\n";
120
				break;
121
		}
122
		$radvdconf .= "\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
123
		switch($dhcpv6ifconf['mode']) {
124
			case "managed":
125
				$radvdconf .= "\t\tAdvOnLink on;\n";
126
				$radvdconf .= "\t\tAdvAutonomous off;\n";
127
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
128
				break;
129
			case "router":
130
				$radvdconf .= "\t\tAdvOnLink off;\n";
131
				$radvdconf .= "\t\tAdvAutonomous off;\n";
132
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
133
				break;
134
			case "assist":
135
				$radvdconf .= "\t\tAdvOnLink on;\n";
136
				$radvdconf .= "\t\tAdvAutonomous on;\n";
137
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
138
				break;
139
			case "unmanaged":
140
				$radvdconf .= "\t\tAdvOnLink on;\n";
141
				$radvdconf .= "\t\tAdvAutonomous on;\n";
142
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
143
				break;				
144
		}
145
		$radvdconf .= "\t};\n";
146

    
147
		/* add DNS servers */
148
		$dnslist = array();
149
		if(!empty($dhcpv6ifconf['dnsserver'][0])) {
150
			foreach($dhcpv6ifconf['dnsserver'] as $server) {
151
				if(is_ipaddrv6($server))
152
					$dnslist[] = $server;
153
			}
154
		} elseif (isset($config['dnsmasq']['enable'])) {
155
			$dnslist[] = get_interface_ipv6($dhcpv6if);
156
		} elseif (!empty($config['system']['dnsserver'][0])) {
157
			foreach($config['system']['dnsserver'] as $server) {
158
				if(is_ipaddrv6($server))
159
					$dnslist[] = $server;
160
			}
161
		}
162
		if(count($dnslist) > 0) {
163
			$dnsstring = implode(" ", $dnslist);
164
			if($dnsstring <> "")
165
				$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
166
		}
167
		if($dhcpv6ifconf['domain'] <> "") {
168
			$radvdconf .= "\tDNSSL {$dhcpv6ifconf['domain']} { };\n";
169
		} elseif ($config['system']['domain'] <> "") {
170
			$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
171
		}
172
		$radvdconf .= "};\n";
173
		$radvdnum++;
174
	}
175

    
176
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
177
	foreach ($Iflist as $if => $ifdescr) {
178
		if(!isset($config['interfaces'][$if]['track6-interface']))
179
			continue;
180
		if(!isset($config['interfaces'][$if]['enable']))
181
			continue;
182
			
183
		$realif = get_real_interface($if);
184
		/* prevent duplicate entries, manual overrides */
185
		if(in_array($realif, $radvdifs))
186
			continue;
187

    
188
		$ifcfgipv6 = get_interface_ipv6($if);
189
		if(!is_ipaddrv6($ifcfgipv6))
190
			continue;
191

    
192
		$ifcfgsnv6 = get_interface_subnetv6($if);
193
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
194
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
195
		$trackif = $config['interfaces'][$if]['track6-interface'];
196
		$radvdifs[] = $realif;
197

    
198
		$autotype = $config['interfaces'][$trackif]['ipaddrv6'];
199
	
200
		log_error("configuring RA on {$if} for type {$autotype} radvd subnet {$subnetv6}/{$ifcfgsnv6}");
201

    
202
		$dnslist = array();
203
		if(is_ipaddrv6($subnetv6)) {
204
			$radvdconf .= "# Generated config for {$autotype} delegation from {$trackif} on {$if}\n";
205
			$radvdconf .= "interface {$realif} {\n";
206
				$radvdconf .= "\tAdvSendAdvert on;\n";
207
				$radvdconf .= "\tMinRtrAdvInterval 3;\n";
208
				$radvdconf .= "\tMaxRtrAdvInterval 10;\n";
209
				$radvdconf .= "\tAdvLinkMTU 1280;\n";
210
				$radvdconf .= "\tAdvOtherConfigFlag on;\n";
211
					$radvdconf .= "\t\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
212
					$radvdconf .= "\t\tAdvOnLink on;\n";
213
					$radvdconf .= "\t\tAdvAutonomous on;\n";
214
					$radvdconf .= "\t\tAdvRouterAddr on;\n";
215
				$radvdconf .= "\t};\n";
216

    
217
				/* add DNS servers */
218
				$dnslist = array();
219
				if (isset($config['dnsmasq']['enable'])) {
220
						$dnslist[] = $ifcfgipv6;
221
				} elseif (!empty($config['system']['dnsserver'][0])) {
222
					foreach($config['system']['dnsserver'] as $server) {
223
						if(is_ipaddrv6($server))
224
							$dnslist[] = $server;
225
					}
226
				}
227
				if(count($dnslist) > 0) {
228
					$dnsstring = implode(" ", $dnslist);
229
					if($dnsstring <> "")
230
						$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
231
				}
232
				if ($config['system']['domain'] <> "") {
233
					$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
234
				}
235
			$radvdconf .= "};\n";
236
			$radvdnum++;
237
		}
238
	}
239

    
240
	fwrite($fd, $radvdconf);
241
	fclose($fd);
242

    
243
	if(count($radvdifs) > 0) {
244
		mwexec("/usr/local/sbin/radvd -C {$g['varetc_path']}/radvd.conf -m syslog");
245
	}
246
	return 0;
247
}
248

    
249
function services_dhcpd_configure() {
250
	global $config, $g;
251

    
252
	/* configure DHCPD chroot once */
253
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
254
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
255
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
256
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
257
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
258
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
259
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
260
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
261
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
262
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
263
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
264
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
265
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
266
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
267
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
268

    
269
	if(!trim($status))
270
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
271
	fclose($fd);
272
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
273

    
274
	services_dhcpdv4_configure();
275
	services_dhcpdv6_configure();
276
	services_radvd_configure();
277
	return;
278

    
279
}
280
function services_dhcpdv4_configure() {
281
	global $config, $g;
282

    
283
	if($g['services_dhcp_server_enable'] == false)
284
		return;
285

    
286
	if(isset($config['system']['developerspew'])) {
287
		$mt = microtime();
288
		echo "services_dhcpdv4_configure($if) being called $mt\n";
289
	}
290

    
291
	/* kill any running dhcpd */
292
	if(is_process_running("dhcpd")) {
293
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
294
	}
295

    
296
	/* DHCP enabled on any interfaces? */
297
	if (!is_dhcp_server_enabled())
298
		return 0;
299

    
300
	/* if OLSRD is enabled, allow WAN to house DHCP. */
301
	if($config['installedpackages']['olsrd'])
302
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
303
				if($olsrd['enable'])
304
					$is_olsr_enabled = true;
305

    
306
	if ($g['booting']) {
307
		if ($g['platform'] != "pfSense") {
308
			/* restore the leases, if we have them */
309
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
310
				$dhcprestore = "";
311
				$dhcpreturn = "";
312
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
313
				$dhcprestore = implode(" ", $dhcprestore);
314
				if($dhcpreturn <> 0) {
315
					log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n"));
316
				}
317
			}
318
		}
319
	}
320

    
321
	$syscfg = $config['system'];
322
	if (!is_array($config['dhcpd']))
323
		$config['dhcpd'] = array();
324
	$dhcpdcfg = $config['dhcpd'];
325
	$Iflist = get_configured_interface_list();
326

    
327
	if ($g['booting'])
328
		echo gettext("Starting DHCP service...");
329
	else
330
		sleep(1);
331

    
332
	/* write dhcpd.conf */
333
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
334
	if (!$fd) {
335
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
336
		return 1;
337
	}
338

    
339
	$custoptions = "";
340
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
341
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
342
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
343
				if(!empty($item['type']))
344
					$itemtype = $item['type'];
345
				else
346
					$itemtype = "text";
347
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
348
			}
349
		}
350
	}
351

    
352
	$dhcpdconf = <<<EOD
353

    
354
option domain-name "{$syscfg['domain']}";
355
option ldap-server code 95 = text;
356
option domain-search-list code 119 = text;
357
{$custoptions}
358
default-lease-time 7200;
359
max-lease-time 86400;
360
log-facility local7;
361
ddns-update-style none;
362
one-lease-per-client true;
363
deny duplicates;
364
ping-check true;
365

    
366
EOD;
367

    
368
	if(!isset($dhcpifconf['disableauthoritative']))
369
		$dhcpdconf .= "authoritative;\n";
370

    
371
	if(isset($dhcpifconf['alwaysbroadcast']))
372
		$dhcpdconf .= "always-broadcast on\n";
373

    
374
	$dhcpdifs = array();
375

    
376
	/*    loop through and determine if we need to setup
377
	 *    failover peer "bleh" entries
378
	 */
379
	$dhcpnum = 0;
380
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
381

    
382
		interfaces_staticarp_configure($dhcpif);
383

    
384
		if (!isset($dhcpifconf['enable']))
385
			continue;
386

    
387
		if($dhcpifconf['failover_peerip'] <> "") {
388
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
389
			$intip = find_interface_ip($int);
390
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
391
			/*
392
			 *    yep, failover peer is defined.
393
			 *    does it match up to a defined vip?
394
			 */
395
			$skew = 110;
396
			$a_vip = &$config['virtualip']['vip'];
397
			if(is_array($a_vip)) {
398
				foreach ($a_vip as $vipent) {
399
					if($int == $real_dhcpif) {
400
						/* this is the interface! */
401
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
402
							$skew = 0;
403
					}
404
				}
405
			} else {
406
				log_error(gettext("Warning!  DHCP Failover setup and no CARP virtual IP's defined!"));
407
			}
408
			if($skew > 10) {
409
				$type = "secondary";
410
				$dhcpdconf_pri  = "mclt 600;\n";
411
				$my_port = "520";
412
				$peer_port = "519";
413
			} else {
414
				$my_port = "519";
415
				$peer_port = "520";
416
				$type = "primary";
417
				$dhcpdconf_pri  = "split 128;\n";
418
				$dhcpdconf_pri .= "  mclt 600;\n";
419
			}
420
			$dhcpdconf .= <<<EOPP
421
failover peer "dhcp{$dhcpnum}" {
422
  {$type};
423
  address {$intip};
424
  port {$my_port};
425
  peer address {$dhcpifconf['failover_peerip']};
426
  peer port {$peer_port};
427
  max-response-delay 10;
428
  max-unacked-updates 10;
429
  {$dhcpdconf_pri}
430
  load balance max seconds 3;
431
}
432

    
433
EOPP;
434
		$dhcpnum++;
435
		}
436
	}
437

    
438
	$dhcpnum = 0;
439

    
440
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
441

    
442
		$ifcfg = $config['interfaces'][$dhcpif];
443

    
444
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
445
			continue;
446
		$ifcfgip = get_interface_ip($dhcpif);
447
		$ifcfgsn = get_interface_subnet($dhcpif);
448
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
449
		$subnetmask = gen_subnet_mask($ifcfgsn);
450

    
451
		if (!is_ipaddr($subnet))
452
			continue;
453

    
454
		if($is_olsr_enabled == true)
455
			if($dhcpifconf['netmask'])
456
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
457

    
458
		$dnscfg = "";
459

    
460
		if ($dhcpifconf['domain']) {
461
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
462
		}
463

    
464
    		if($dhcpifconf['domainsearchlist'] <> "") {
465
			$dnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpifconf['domainsearchlist'])) . "\";\n";
466
                        $domains = implode(',', array_map(strify, explode(' ', $dhcpifconf['domainsearchlist'])));
467
                        $dnscfg .= "   option domain-search {$domains};\n";
468
    		}
469

    
470
		if (isset($dhcpifconf['ddnsupdate'])) {
471
			if($dhcpifconf['ddnsdomain'] <> "") {
472
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
473
			}
474
			$dnscfg .= "	ddns-update-style interim;\n";
475
		}
476

    
477
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
478
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
479
		} else if (isset($config['dnsmasq']['enable'])) {
480
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
481
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
482
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
483
		}
484

    
485
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
486
		$dhcpdconf .= "	pool {\n";
487

    
488
		/* is failover dns setup? */
489
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
490
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
491
			if($dhcpifconf['dnsserver'][1] <> "")
492
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
493
			$dhcpdconf .= ";\n";
494
		}
495

    
496
		if($dhcpifconf['failover_peerip'] <> "")
497
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
498

    
499
		if (isset($dhcpifconf['denyunknown']))
500
		   $dhcpdconf .= "		deny unknown-clients;\n";
501

    
502
		if ($dhcpifconf['gateway'])
503
			$routers = $dhcpifconf['gateway'];
504
		else
505
			$routers = $ifcfgip;
506

    
507
		if($dhcpifconf['failover_peerip'] <> "") {
508
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
509
			$dhcpnum++;
510
		}
511

    
512
		$dhcpdconf .= <<<EOD
513
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
514
	}
515
	option routers {$routers};
516
$dnscfg
517

    
518
EOD;
519
    		// default-lease-time
520
		if ($dhcpifconf['defaultleasetime'])
521
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
522

    
523
		// max-lease-time
524
		if ($dhcpifconf['maxleasetime'])
525
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
526

    
527
		// netbios-name*
528
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
529
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
530
			$dhcpdconf .= "	option netbios-node-type 8;\n";
531
		}
532

    
533
		// ntp-servers
534
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
535
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
536

    
537
		// tftp-server-name
538
		if ($dhcpifconf['tftp'] <> "")
539
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
540

    
541
		// Handle option, number rowhelper values
542
		$dhcpdconf .= "\n";
543
		if($dhcpifconf['numberoptions']['item']) {
544
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
545
				if(empty($item['type']) || $item['type'] == "text")
546
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
547
				else
548
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
549
			}
550
		}
551

    
552
		// ldap-server
553
		if ($dhcpifconf['ldap'] <> "")
554
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
555

    
556
		// net boot information
557
		if(isset($dhcpifconf['netboot'])) {
558
			if ($dhcpifconf['nextserver'] <> "") {
559
				$dhcpdconf .= "	next-server {$dhcpifconf['nextserver']};\n";
560
			}
561
			if ($dhcpifconf['filename'] <> "") {
562
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
563
			}
564
			if ($dhcpifconf['rootpath'] <> "") {
565
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
566
      		}
567
		}
568

    
569
		$dhcpdconf .= <<<EOD
570
}
571

    
572
EOD;
573

    
574
		/* add static mappings */
575
		if (is_array($dhcpifconf['staticmap'])) {
576

    
577
			$i = 0;
578
			foreach ($dhcpifconf['staticmap'] as $sm) {
579
				$dhcpdconf .= <<<EOD
580
host s_{$dhcpif}_{$i} {
581
	hardware ethernet {$sm['mac']};
582

    
583
EOD;
584
				if ($sm['ipaddr'])
585
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
586

    
587
				if ($sm['hostname']) {
588
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
589
					$dhhostname = str_replace(".", "_", $dhhostname);
590
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
591
				}
592
				if ($sm['filename'])
593
					$dhcpdconf .= "	filename \"{$sm['filename']}\";\n";
594

    
595
				if ($sm['rootpath'])
596
					$dhcpdconf .= "	option root-path \"{$sm['rootpath']}\";\n";
597

    
598
				$dhcpdconf .= "}\n";
599
				$i++;
600
			}
601
		}
602

    
603
		$dhcpdifs[] = get_real_interface($dhcpif);
604
	}
605

    
606
	fwrite($fd, $dhcpdconf);
607
	fclose($fd);
608

    
609
	/* create an empty leases database */
610
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
611

    
612

    
613
	/* fire up dhcpd in a chroot */
614
	if(count($dhcpdifs) > 0) {
615
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
616
			join(" ", $dhcpdifs));
617
	}
618

    
619
	if ($g['booting']) {
620
		print "done.\n";
621
	}
622

    
623
	return 0;
624
}
625

    
626
function services_dhcpdv6_configure() {
627
	global $config, $g;
628

    
629
	if($g['services_dhcp_server_enable'] == false)
630
		return;
631

    
632
	if(isset($config['system']['developerspew'])) {
633
		$mt = microtime();
634
		echo "services_dhcpd_configure($if) being called $mt\n";
635
	}
636

    
637
	/* kill any running dhcpd */
638
	if(is_process_running("dhcpd")) {
639
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
640
	}
641

    
642
	/* DHCP enabled on any interfaces? */
643
	if (!is_dhcpv6_server_enabled())
644
		return 0;
645

    
646
	if ($g['booting']) {
647
		if ($g['platform'] != "pfSense") {
648
			/* restore the leases, if we have them */
649
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
650
				$dhcprestore = "";
651
				$dhcpreturn = "";
652
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
653
				$dhcprestore = implode(" ", $dhcprestore);
654
				if($dhcpreturn <> 0) {
655
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
656
				}
657
			}
658
		}
659
	}
660

    
661
	$syscfg = $config['system'];
662
	if (!is_array($config['dhcpdv6']))
663
		$config['dhcpdv6'] = array();
664
	$dhcpdv6cfg = $config['dhcpdv6'];
665
	$Iflist = get_configured_interface_list();
666

    
667
	if ($g['booting'])
668
		echo "Starting DHCPv6 service...";
669
	else
670
		sleep(1);
671

    
672
	/* we add a fake entry for interfaces that are set to track6 another WAN */
673
	foreach($Iflist as $ifname) {
674
		$realif = get_real_interface($ifname);
675
		$ifcfgipv6 = find_interface_ipv6($realif);
676
		if(!is_ipaddrv6($ifcfgipv6))
677
			continue;
678
		$ifcfgipv6 = Net_IPv6::getNetmask($ifcfgipv6, 64);
679
		if($config['interfaces'][$ifname]['track6-interface'] <> "") {
680
			$trackifname = $config['interfaces'][$ifname]['track6-interface'];
681
			$trackcfg = $config['interfaces'][$trackifname];
682
			/* determine possible prefix length */
683
			switch($trackcfg['ipaddrv6']) {
684
				case "6to4":
685
					$pdlen = 16;
686
					break;
687
				case "6rd":
688
					$rd6plen = explode("/", $rd6cfg['prefix-6rd']);
689
					$pdlen =(64 - ($rd6plen[1] + (32 - $trackcfg['prefix-6rd-v4plen'])));
690
					break;
691
				case "dhcp6":
692
					$pdlen = $trackcfg['dhcp6-ia-pd-len'];
693
					break;
694
			}
695
			$ifcfgipv6arr =explode(":", $ifcfgipv6);
696
			$dhcpdv6cfg[$ifname] = array();
697
			$dhcpdv6cfg[$ifname]['enable'] = true;
698
			/* range */
699
			$ifcfgipv6arr[7] = "1000";
700
			$dhcpdv6cfg[$ifname]['range']['from'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));
701
			$ifcfgipv6arr[7] = "2000";
702
			$dhcpdv6cfg[$ifname]['range']['to'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));;
703
			/* prefix length > 0? We can add dhcp6 prefix delegation server */
704
			if($pdlen > 2) {
705
				$pdlenmax = $pdlen;
706
				$pdlenhalf = $pdlenmax -1;
707
				$pdlenmin = (64 - ceil($pdlenhalf / 4));
708
				$dhcpdv6cfg[$ifname]['prefixrange']['prefixlength'] = $pdlenmin;
709

    
710
				/* set the delegation start to half the current address block */
711
				$range = Net_IPv6::parseAddress($ifcfgipv6, (64 - $pdlenmax));
712
				$range['start'] = Net_IPv6::getNetmask($range['end'], (64 - $pdlenhalf));
713

    
714
				/* set the end range to a multiple of the prefix delegation size, required by dhcpd */
715
				$range = Net_IPv6::parseAddress($range['end'], (64 - $pdlenhalf));
716
				$range['end'] = Net_IPv6::getNetmask($range['end'], (64 - round($pdlen / 2)));
717

    
718
				$dhcpdv6cfg[$ifname]['prefixrange']['from'] = Net_IPv6::compress($range['start']);
719
				$dhcpdv6cfg[$ifname]['prefixrange']['to'] = Net_IPv6::compress($range['end']);
720
			}
721
		}
722
	}
723

    
724
	/* write dhcpdv6.conf */
725
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
726
	if (! $fdv6) {
727
		printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n");
728
		return 1;
729
	}
730

    
731
	$custoptionsv6 = "";
732
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
733
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
734
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
735
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
736
			}
737
		}
738
	}
739

    
740
	$dhcpdv6conf = <<<EOD
741

    
742
option domain-name "{$syscfg['domain']}";
743
option ldap-server code 95 = text;
744
option domain-search-list code 119 = text;
745
{$custoptions}
746
default-lease-time 7200;
747
max-lease-time 86400;
748
log-facility local7;
749
ddns-update-style none;
750
one-lease-per-client true;
751
deny duplicates;
752
ping-check true;
753

    
754
EOD;
755

    
756
	if(!isset($dhcpv6ifconf['disableauthoritative']))
757
		$dhcpdv6conf .= "authoritative;\n";
758

    
759
	if(isset($dhcpv6ifconf['alwaysbroadcast']))
760
		$dhcpdv6conf .= "always-broadcast on\n";
761

    
762
	$dhcpdv6ifs = array();
763

    
764
	/*    loop through and determine if we need to setup
765
	 *    failover peer "bleh" entries
766
	 */
767
	$dhcpv6num = 0;
768
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
769

    
770
		if (!isset($dhcpv6ifconf['enable']))
771
			continue;
772

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

    
819
EOPP;
820
		$dhcpv6num++;
821
		}
822
	}
823

    
824
	$dhcpv6num = 0;
825
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
826

    
827
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
828

    
829
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
830
			continue;
831
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
832
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
833
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
834
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
835

    
836
		if($is_olsr_enabled == true)
837
			if($dhcpv6ifconf['netmask'])
838
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
839

    
840
		$dnscfgv6 = "";
841

    
842
		if ($dhcpv6ifconf['domain']) {
843
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
844
		}
845

    
846
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
847
			$dnscfgv6 .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpv6ifconf['domainsearchlist'])) . "\";\n";
848
    		}
849

    
850
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
851
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
852
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
853
			}
854
			$dnscfgv6 .= "	ddns-update-style interim;\n";
855
		}
856

    
857
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
858
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
859
		} else if (isset($config['dnsmasq']['enable'])) {
860
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
861
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
862
			$dns_arrv6 = array();
863
			foreach($syscfg['dnsserver'] as $dnsserver) {
864
				if(is_ipaddrv6($dnsserver)) {
865
					$dns_arrv6[] = $dnsserver;
866
				}
867
			}
868
			if(!empty($dns_arrv6))
869
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
870
		}
871

    
872
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
873
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
874

    
875
		/* is failover dns setup? */
876
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
877
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
878
			if($dhcpv6ifconf['dnsserver'][1] <> "")
879
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
880
			$dhcpdv6conf .= ";\n";
881
		}
882

    
883
		if($dhcpv6ifconf['failover_peerip'] <> "")
884
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
885

    
886
		if (isset($dhcpv6ifconf['denyunknown']))
887
		   $dhcpdv6conf .= "		deny unknown-clients;\n";
888

    
889
		if($dhcpv6ifconf['failover_peerip'] <> "") {
890
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
891
			$dhcpv6num++;
892
		}
893

    
894
		$dhcpdv6conf .= <<<EOD
895
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
896
$dnscfgv6
897

    
898
EOD;
899

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

    
903
		}
904
    		// default-lease-time
905
		if ($dhcpv6ifconf['defaultleasetime'])
906
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
907

    
908
		// max-lease-time
909
		if ($dhcpv6ifconf['maxleasetime'])
910
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
911

    
912
		// ntp-servers
913
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) {
914
			$ntpservers = array();
915
			foreach($dhcpv6ifconf['ntpserver'] as $ntpserver) {
916
				if(is_ipaddrv6($ntpserver))
917
					$ntpservers[] = $ntpserver;
918
			}
919
			if(count($ntpservers) > 0 )
920
				$dhcpdv6conf .= "       option dhcp6.sntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
921
		}
922
		// tftp-server-name
923
		/* Needs ISC DHCPD support
924
		 if ($dhcpv6ifconf['tftp'] <> "")
925
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
926
		*/
927

    
928
		// Handle option, number rowhelper values
929
		$dhcpdv6conf .= "\n";
930
		if($dhcpv6ifconf['numberoptions']['item']) {
931
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
932
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
933
			}
934
		}
935

    
936
		// ldap-server
937
		if ($dhcpv6ifconf['ldap'] <> "")
938
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
939

    
940
		// net boot information
941
		if(isset($dhcpv6ifconf['netboot'])) {
942
			if ($dhcpv6ifconf['nextserver'] <> "") {
943
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['nextserver']};\n";
944
			}
945
			if ($dhcpv6ifconf['filename'] <> "") {
946
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
947
			}
948
			if ($dhcpv6ifconf['rootpath'] <> "") {
949
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
950
      		}
951
	}
952

    
953
		$dhcpdv6conf .= <<<EOD
954
}
955

    
956
EOD;
957

    
958
		/* add static mappings */
959
		/* Needs to use DUID */
960
		if (is_array($dhcpv6ifconf['staticmap'])) {
961

    
962
			$i = 0;
963
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
964
				$dhcpdv6conf .= <<<EOD
965
host s_{$dhcpv6if}_{$i} {
966
	host-identifier option dhcp6.client-id {$sm['duid']};
967

    
968
EOD;
969
				if ($sm['ipaddrv6'])
970
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
971

    
972
				if ($sm['hostname']) {
973
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
974
					$dhhostname = str_replace(".", "_", $dhhostname);
975
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
976
				}
977
				if ($sm['filename'])
978
					$dhcpdv6conf .= "	filename \"{$sm['filename']}\";\n";
979

    
980
				if ($sm['rootpath'])
981
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
982

    
983
				$dhcpdv6conf .= "}\n";
984
				$i++;
985
			}
986
		}
987

    
988
		if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") {
989
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
990
			$dhcpdv6ifs[] = $realif;
991
			exec("/sbin/ifconfig {$realif} |awk  '/ether/ {print $2}'", $mac);
992
			$v6address = generate_ipv6_from_mac($mac[0]);
993
			/* Create link local address for bridges */
994
			if(stristr("$realif", "bridge")) {
995
				mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
996
			}
997
		}
998
	}
999

    
1000
	fwrite($fdv6, $dhcpdv6conf);
1001
	fclose($fdv6);
1002
	/* create an empty leases v6 database */
1003
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1004

    
1005

    
1006
	/* fire up dhcpd in a chroot */
1007
	if(count($dhcpdv6ifs) > 0) {
1008
		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 " .
1009
			join(" ", $dhcpdv6ifs));
1010
		mwexec("/usr/local/sbin/dhcpleases6 -c \"/usr/local/bin/php -f /usr/local/sbin/prefixes.php|/bin/sh\" -l {$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1011
	}
1012

    
1013
	if ($g['booting']) {
1014
		print gettext("done.") . "\n";
1015
	}
1016

    
1017
	return 0;
1018
}
1019

    
1020
function services_igmpproxy_configure() {
1021
        global $config, $g;
1022

    
1023
        /* kill any running igmpproxy */
1024
        killbyname("igmpproxy");
1025

    
1026
	if (!is_array($config['igmpproxy']['igmpentry']))
1027
		return 1;
1028

    
1029
        $iflist = get_configured_interface_list();
1030

    
1031
        $igmpconf = <<<EOD
1032

    
1033
##------------------------------------------------------
1034
## Enable Quickleave mode (Sends Leave instantly)
1035
##------------------------------------------------------
1036
quickleave
1037

    
1038
EOD;
1039

    
1040
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
1041
                unset($iflist[$igmpcf['ifname']]);
1042
                $realif = get_real_interface($igmpcf['ifname']);
1043
                if (empty($igmpcf['threshold']))
1044
                        $threshld = 1;
1045
                else
1046
                        $threshld = $igmpcf['threshold'];
1047
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
1048

    
1049
                if ($igmpcf['address'] <> "") {
1050
                        $item = explode(" ", $igmpcf['address']);
1051
                        foreach($item as $iww)
1052
                                $igmpconf .= "altnet {$iww}\n";
1053
                }
1054
                $igmpconf .= "\n";
1055
        }
1056
        foreach ($iflist as $ifn) {
1057
                $realif = get_real_interface($ifn);
1058
                $igmpconf .= "phyint {$realif} disabled\n";
1059
        }
1060
	$igmpconf .= "\n";
1061

    
1062
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
1063
        if (!$igmpfl) {
1064
                log_error(gettext("Could not write Igmpproxy configuration file!"));
1065
                return;
1066
        }
1067
        fwrite($igmpfl, $igmpconf);
1068
        fclose($igmpfl);
1069

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

    
1073
        return 0;
1074
}
1075

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

    
1085
	/* kill any running dhcrelay */
1086
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1087

    
1088
	$dhcrelaycfg =& $config['dhcrelay'];
1089

    
1090
	/* DHCPRelay enabled on any interfaces? */
1091
	if (!isset($dhcrelaycfg['enable']))
1092
		return 0;
1093

    
1094
	if ($g['booting'])
1095
		echo gettext("Starting DHCP relay service...");
1096
	else
1097
		sleep(1);
1098

    
1099
	$iflist = get_configured_interface_list();
1100

    
1101
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1102
	foreach ($dhcifaces as $dhcrelayif) {
1103
		if (!isset($iflist[$dhcrelayif]) ||
1104
			link_interface_to_bridge($dhcrelayif))
1105
			continue;
1106

    
1107
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
1108
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1109
	}
1110

    
1111
	/*
1112
	 * In order for the relay to work, it needs to be active
1113
	 * on the interface in which the destination server sits.
1114
	 */
1115
	$srvips = explode(",", $dhcrelaycfg['server']);
1116
	foreach ($srvips as $srcidx => $srvip) {
1117
		unset($destif);
1118
		foreach ($iflist as $ifname) {
1119
			$subnet = get_interface_ip($ifname);
1120
			if (!is_ipaddr($subnet))
1121
				continue;
1122
			$subnet .=  "/" . get_interface_subnet($ifname);
1123
			if (ip_in_subnet($srvip, $subnet)) {
1124
				$destif = get_real_interface($ifname);
1125
				break;
1126
			}
1127
		}
1128
		if (!isset($destif)) {
1129
			if (is_array($config['staticroutes']['route'])) {
1130
				foreach ($config['staticroutes']['route'] as $rtent) {
1131
					if (ip_in_subnet($srvip, $rtent['network'])) {
1132
						$a_gateways = return_gateways_array(true);
1133
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1134
						break;
1135
					}
1136
				}
1137
			}
1138
		}
1139

    
1140
		if (!isset($destif)) {
1141
			/* Create a array from the existing route table */
1142
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
1143
        		array_shift($route_str);
1144
        		array_shift($route_str);
1145
        		array_shift($route_str);
1146
        		array_shift($route_str);
1147
        		$route_arr = array();
1148
        		foreach($route_str as $routeline) {
1149
                		$items = preg_split("/[ ]+/i", $routeline);
1150
				if (ip_in_subnet($srvip, $items[0])) {
1151
					$destif = trim($items[6]);
1152
					break;
1153
				}
1154
        		}
1155
		}
1156

    
1157
		if (!isset($destif)) {
1158
			if (is_array($config['gateways']['gateway_item'])) {
1159
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1160
					if (isset($gateway['defaultgw'])) {
1161
						$a_gateways = return_gateways_array(true);
1162
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1163
						break;
1164
					}
1165
				}
1166
			} else
1167
				$destif = get_real_interface("wan");
1168
		}
1169

    
1170
		if (!empty($destif))
1171
			$dhcrelayifs[] = $destif;
1172
	}
1173
	$dhcrelayifs = array_unique($dhcrelayifs);
1174

    
1175
	/* fire up dhcrelay */
1176
	if (empty($dhcrelayifs)) {
1177
		log_error("No suitable interface found for running dhcrelay!");
1178
		return; /* XXX */
1179
	}
1180

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

    
1183
	if (isset($dhcrelaycfg['agentoption']))
1184
		$cmd .=  " -a -m replace";
1185

    
1186
	$cmd .= " " . implode(" ", $srvips);
1187
	mwexec($cmd);
1188

    
1189
	return 0;
1190
}
1191

    
1192
function services_dhcrelay6_configure() {
1193
	global $config, $g;
1194
	if ($g['platform'] == 'jail')
1195
		return;
1196
	if(isset($config['system']['developerspew'])) {
1197
		$mt = microtime();
1198
		echo "services_dhcrelay_configure() being called $mt\n";
1199
	}
1200

    
1201
	/* kill any running dhcrelay */
1202
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1203

    
1204
	$dhcrelaycfg =& $config['dhcrelay6'];
1205

    
1206
	/* DHCPv6 Relay enabled on any interfaces? */
1207
	if (!isset($dhcrelaycfg['enable']))
1208
		return 0;
1209

    
1210
	if ($g['booting'])
1211
		echo gettext("Starting DHCPv6 relay service...");
1212
	else
1213
		sleep(1);
1214

    
1215
	$iflist = get_configured_interface_list();
1216

    
1217
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1218
	foreach ($dhcifaces as $dhcrelayif) {
1219
		if (!isset($iflist[$dhcrelayif]) ||
1220
			link_interface_to_bridge($dhcrelayif))
1221
			continue;
1222

    
1223
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif)))
1224
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1225
	}
1226

    
1227
	/*
1228
	 * In order for the relay to work, it needs to be active
1229
	 * on the interface in which the destination server sits.
1230
	 */
1231
	$srvips = explode(",", $dhcrelaycfg['server']);
1232
	foreach ($srvips as $srcidx => $srvip) {
1233
		unset($destif);
1234
		foreach ($iflist as $ifname) {
1235
			$subnet = get_interface_ipv6($ifname);
1236
			if (!is_ipaddrv6($subnet))
1237
				continue;
1238
			$subnet .=  "/" . get_interface_subnetv6($ifname);
1239
			if (ip_in_subnet($srvip, $subnet)) {
1240
				$destif = get_real_interface($ifname);
1241
				break;
1242
			}
1243
		}
1244
		if (!isset($destif)) {
1245
			if (is_array($config['staticroutes']['route'])) {
1246
				foreach ($config['staticroutes']['route'] as $rtent) {
1247
					if (ip_in_subnet($srvip, $rtent['network'])) {
1248
						$a_gateways = return_gateways_array(true);
1249
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1250
						break;
1251
					}
1252
				}
1253
			}
1254
		}
1255

    
1256
		if (!isset($destif)) {
1257
			/* Create a array from the existing route table */
1258
        		exec("/usr/bin/netstat -rnWf inet6", $route_str);
1259
        		array_shift($route_str);
1260
        		array_shift($route_str);
1261
        		array_shift($route_str);
1262
        		array_shift($route_str);
1263
        		$route_arr = array();
1264
        		foreach($route_str as $routeline) {
1265
                		$items = preg_split("/[ ]+/i", $routeline);
1266
				if (ip_in_subnet($srvip, $items[0])) {
1267
					$destif = trim($items[6]);
1268
					break;
1269
				}
1270
        		}
1271
		}
1272

    
1273
		if (!isset($destif)) {
1274
			if (is_array($config['gateways']['gateway_item'])) {
1275
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1276
					if (isset($gateway['defaultgw'])) {
1277
						$a_gateways = return_gateways_array(true);
1278
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1279
						break;
1280
					}
1281
				}
1282
			} else
1283
				$destif = get_real_interface("wan");
1284
		}
1285

    
1286
		if (!empty($destif))
1287
			$dhcrelayifs[] = $destif;
1288
	}
1289
	$dhcrelayifs = array_unique($dhcrelayifs);
1290

    
1291
	/* fire up dhcrelay */
1292
	if (empty($dhcrelayifs)) {
1293
		log_error("No suitable interface found for running dhcrelay -6!");
1294
		return; /* XXX */
1295
	}
1296

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

    
1299
	if (isset($dhcrelaycfg['agentoption']))
1300
		$cmd .=  " -a -m replace";
1301

    
1302
	$cmd .= " " . implode(" ", $srvips);
1303
	mwexec($cmd);
1304

    
1305
	return 0;
1306
}
1307

    
1308
function services_dyndns_configure_client($conf) {
1309

    
1310
	if (!isset($conf['enable']))
1311
		return;
1312

    
1313
	/* load up the dyndns.class */
1314
	require_once("dyndns.class");
1315

    
1316
	$dns = new updatedns($dnsService = $conf['type'],
1317
		$dnsHost = $conf['host'],
1318
		$dnsUser = $conf['username'],
1319
		$dnsPass = $conf['password'],
1320
		$dnsWilcard = $conf['wildcard'],
1321
		$dnsMX = $conf['mx'],
1322
		$dnsIf = "{$conf['interface']}",
1323
		$dnsBackMX = NULL,
1324
		$dnsServer = NULL,
1325
		$dnsPort = NULL,
1326
		$dnsUpdateURL = NULL,
1327
		$forceUpdate = $conf['force'],
1328
                $dnsZoneID=$conf['zoneid'],
1329
                $dnsTTL=$conf['ttl']);
1330
}
1331

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

    
1339
	$dyndnscfg = $config['dyndnses']['dyndns'];
1340

    
1341
	if (is_array($dyndnscfg)) {
1342
		if ($g['booting'])
1343
			echo gettext("Starting DynDNS clients...");
1344

    
1345
		foreach ($dyndnscfg as $dyndns) {
1346
			if (!empty($int) && $int != $dyndns['interface'])
1347
				continue;
1348

    
1349
			services_dyndns_configure_client($dyndns);
1350

    
1351
			sleep(1);
1352
		}
1353

    
1354
		if ($g['booting'])
1355
			echo gettext("done.") . "\n";
1356
	}
1357

    
1358
	return 0;
1359
}
1360

    
1361
function services_dnsmasq_configure() {
1362
	global $config, $g;
1363
	$return = 0;
1364

    
1365
	if(isset($config['system']['developerspew'])) {
1366
		$mt = microtime();
1367
		echo "services_dnsmasq_configure() being called $mt\n";
1368
	}
1369

    
1370
	/* kill any running dnsmasq */
1371
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
1372
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1373

    
1374
	if (isset($config['dnsmasq']['enable'])) {
1375

    
1376
		if ($g['booting'])
1377
			echo gettext("Starting DNS forwarder...");
1378
		else
1379
			sleep(1);
1380

    
1381
		/* generate hosts file */
1382
		if(system_hosts_generate()!=0)
1383
			$return = 1;
1384

    
1385
		$args = "";
1386

    
1387
		if (isset($config['dnsmasq']['regdhcp'])) {
1388
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1389
		}
1390

    
1391
		/* Setup forwarded domains */
1392
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1393
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1394
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1395
			}
1396
		}
1397

    
1398
		/* Allow DNS Rebind for forwarded domains */
1399
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1400
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1401
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1402
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1403
				}
1404
			}
1405
		}
1406

    
1407
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1408
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1409

    
1410
		if ($config['dnsmasq']['custom_options']) {
1411
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1412
				$args .= " --$c";
1413
		}
1414

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

    
1418
		if ($g['booting'])
1419
			echo gettext("done.") . "\n";
1420
	}
1421

    
1422
	if (!$g['booting']) {
1423
		if(services_dhcpd_configure()!=0)
1424
			$return = 1;
1425
	}
1426

    
1427
	return $return;
1428
}
1429

    
1430
function services_unbound_configure() {
1431
	global $config, $g;
1432
	$return = 0;
1433

    
1434
	if(isset($config['system']['developerspew'])) {
1435
		$mt = microtime();
1436
		echo "services_unbound_configure() being called $mt\n";
1437
	}
1438

    
1439
	/* kill any running unbound */
1440
	sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1441

    
1442
	if (isset($config['unbound']['enable'])) {
1443

    
1444
		if ($g['booting'])
1445
			echo "Starting Unbound DNS...";
1446
		else
1447
			sleep(1);
1448

    
1449
		/* Setup Unbound DHCP Chroot environment */
1450
		$fd = fopen("{$g['tmp_path']}/unbound.sh","w");
1451
		$status = `/sbin/mount | /usr/bin/grep "{$g['unbound_chroot_path']}/dev"`;
1452
		fwrite($fd, "mkdir -p {$g['unbound_chroot_path']}\n");
1453
		fwrite($fd, "mkdir -p {$g['unbound_chroot_path']}/dev\n");
1454
		fwrite($fd, "mkdir -p {$g['unbound_chroot_path']}/etc\n");
1455
		if(!trim($status))
1456
			fwrite($fd, "mount -t devfs devfs {$g['unbound_chroot_path']}/dev\n");
1457
		fclose($fd);
1458
		mwexec("/bin/sh {$g['tmp_path']}/unbound.sh");
1459

    
1460
		/* generate Unbound config file */
1461
		if(unbound_generate_config()!=0) {
1462
			log_error("Problem generating Unbound configuration.");
1463
			$return = 1;
1464
		}
1465

    
1466
		/* run Unbound */
1467
		mwexec("/usr/local/sbin/unbound -c {$g['unbound_chroot_path']}/etc/unbound.conf");
1468

    
1469
		if ($g['booting'])
1470
			echo "done.\n";
1471
	}
1472

    
1473
	return $return;
1474
}
1475

    
1476
function services_snmpd_configure() {
1477
	global $config, $g;
1478
	if(isset($config['system']['developerspew'])) {
1479
		$mt = microtime();
1480
		echo "services_snmpd_configure() being called $mt\n";
1481
	}
1482

    
1483
	/* kill any running snmpd */
1484
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1485
	sleep(2);
1486
	if(is_process_running("bsnmpd"))
1487
		mwexec("/usr/bin/killall bsnmpd", true);
1488

    
1489
	if (isset($config['snmpd']['enable'])) {
1490

    
1491
		if ($g['booting'])
1492
			echo gettext("Starting SNMP daemon... ");
1493

    
1494
		/* generate snmpd.conf */
1495
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1496
		if (!$fd) {
1497
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1498
			return 1;
1499
		}
1500

    
1501

    
1502
		$snmpdconf = <<<EOD
1503
location := "{$config['snmpd']['syslocation']}"
1504
contact := "{$config['snmpd']['syscontact']}"
1505
read := "{$config['snmpd']['rocommunity']}"
1506

    
1507
EOD;
1508

    
1509
/* No docs on what write strings do there for disable for now.
1510
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1511
		    $snmpdconf .= <<<EOD
1512
# write string
1513
write := "{$config['snmpd']['rwcommunity']}"
1514

    
1515
EOD;
1516
		}
1517
*/
1518

    
1519

    
1520
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1521
		    $snmpdconf .= <<<EOD
1522
# SNMP Trap support.
1523
traphost := {$config['snmpd']['trapserver']}
1524
trapport := {$config['snmpd']['trapserverport']}
1525
trap := "{$config['snmpd']['trapstring']}"
1526

    
1527

    
1528
EOD;
1529
		}
1530

    
1531

    
1532
		$snmpdconf .= <<<EOD
1533
system := 1     # pfSense
1534
%snmpd
1535
begemotSnmpdDebugDumpPdus       = 2
1536
begemotSnmpdDebugSyslogPri      = 7
1537
begemotSnmpdCommunityString.0.1 = $(read)
1538

    
1539
EOD;
1540

    
1541
/* No docs on what write strings do there for disable for now.
1542
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1543
		    $snmpdconf .= <<<EOD
1544
begemotSnmpdCommunityString.0.2 = $(write)
1545

    
1546
EOD;
1547
		}
1548
*/
1549

    
1550

    
1551
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1552
		    $snmpdconf .= <<<EOD
1553
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1554
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1555
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1556

    
1557
EOD;
1558
		}
1559

    
1560

    
1561
		$snmpdconf .= <<<EOD
1562
begemotSnmpdCommunityDisable    = 1
1563

    
1564
EOD;
1565

    
1566
		if (isset($config['snmpd']['bindlan'])) {
1567
			$config['snmpd']['bindip'] = 'lan';
1568
			unset($config['snmpd']['bindlan']);
1569
		}
1570
		$bind_to_ip = "0.0.0.0";
1571
		if(isset($config['snmpd']['bindip'])) {
1572
			if (is_ipaddr($config['snmpd']['bindip'])) {
1573
				$bind_to_ip = $config['snmpd']['bindip'];
1574
			} else {
1575
				$if = get_real_interface($config['snmpd']['bindip']);
1576
				if (does_interface_exist($if))
1577
					$bind_to_ip = find_interface_ip($if);
1578
			}
1579
		}
1580

    
1581
		if(is_port( $config['snmpd']['pollport'] )) {
1582
		    $snmpdconf .= <<<EOD
1583
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1584

    
1585
EOD;
1586

    
1587
		}
1588

    
1589
		$snmpdconf .= <<<EOD
1590
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1591
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1592

    
1593
# These are bsnmp macros not php vars.
1594
sysContact      = $(contact)
1595
sysLocation     = $(location)
1596
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1597

    
1598
snmpEnableAuthenTraps = 2
1599

    
1600
EOD;
1601

    
1602
		if (is_array( $config['snmpd']['modules'] )) {
1603
		    if(isset($config['snmpd']['modules']['mibii'])) {
1604
			$snmpdconf .= <<<EOD
1605
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1606

    
1607
EOD;
1608
		    }
1609

    
1610
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1611
			$snmpdconf .= <<<EOD
1612
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1613
%netgraph
1614
begemotNgControlNodeName = "snmpd"
1615

    
1616
EOD;
1617
		    }
1618

    
1619
		    if(isset($config['snmpd']['modules']['pf'])) {
1620
			$snmpdconf .= <<<EOD
1621
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1622

    
1623
EOD;
1624
		    }
1625

    
1626
		    if(isset($config['snmpd']['modules']['hostres'])) {
1627
			$snmpdconf .= <<<EOD
1628
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1629

    
1630
EOD;
1631
		    }
1632
		    if(isset($config['snmpd']['modules']['bridge'])) {
1633
			$snmpdconf .= <<<EOD
1634
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1635
# config must end with blank line
1636

    
1637

    
1638
EOD;
1639
		    }
1640
		}
1641

    
1642
		fwrite($fd, $snmpdconf);
1643
		fclose($fd);
1644

    
1645
		if (isset($config['snmpd']['bindlan'])) {
1646
			$bindlan = "";
1647
		}
1648

    
1649
		/* run bsnmpd */
1650
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1651
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1652

    
1653
		if ($g['booting'])
1654
			echo gettext("done.") . "\n";
1655
	}
1656

    
1657
	return 0;
1658
}
1659

    
1660
function services_dnsupdate_process($int = "") {
1661
	global $config, $g;
1662
	if(isset($config['system']['developerspew'])) {
1663
		$mt = microtime();
1664
		echo "services_dnsupdate_process() being called $mt\n";
1665
	}
1666

    
1667
	/* Dynamic DNS updating active? */
1668
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1669
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1670
			if (!isset($dnsupdate['enable']))
1671
				continue;
1672
			if (!empty($int) && $int != $dnsupdate['interface'])
1673
				continue;
1674

    
1675
			/* determine interface name */
1676
			$if = get_real_interface($dnsupdate['interface']);
1677
			$wanip = get_interface_ip($dnsupdate['interface']);
1678
			if ($wanip) {
1679

    
1680
				$keyname = $dnsupdate['keyname'];
1681
				/* trailing dot */
1682
				if (substr($keyname, -1) != ".")
1683
					$keyname .= ".";
1684

    
1685
				$hostname = $dnsupdate['host'];
1686
				/* trailing dot */
1687
				if (substr($hostname, -1) != ".")
1688
					$hostname .= ".";
1689

    
1690
				/* write private key file
1691
				   this is dumb - public and private keys are the same for HMAC-MD5,
1692
				   but nsupdate insists on having both */
1693
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1694
				$privkey = <<<EOD
1695
Private-key-format: v1.2
1696
Algorithm: 157 (HMAC)
1697
Key: {$dnsupdate['keydata']}
1698

    
1699
EOD;
1700
				fwrite($fd, $privkey);
1701
				fclose($fd);
1702

    
1703
				/* write public key file */
1704
				if ($dnsupdate['keytype'] == "zone") {
1705
					$flags = 257;
1706
					$proto = 3;
1707
				} else if ($dnsupdate['keytype'] == "host") {
1708
					$flags = 513;
1709
					$proto = 3;
1710
				} else if ($dnsupdate['keytype'] == "user") {
1711
					$flags = 0;
1712
					$proto = 2;
1713
				}
1714

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

    
1719
				/* generate update instructions */
1720
				$upinst = "";
1721
				if (!empty($dnsupdate['server']))
1722
					$upinst .= "server {$dnsupdate['server']}\n";
1723
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1724
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1725
				$upinst .= "\n";	/* mind that trailing newline! */
1726

    
1727
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1728
				fwrite($fd, $upinst);
1729
				fclose($fd);
1730

    
1731
				/* invoke nsupdate */
1732
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1733
				if (isset($dnsupdate['usetcp']))
1734
					$cmd .= " -v";
1735
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1736

    
1737
				mwexec_bg($cmd);
1738
			}
1739
		}
1740
	}
1741

    
1742
	return 0;
1743
}
1744

    
1745
function setup_wireless_olsr() {
1746
	global $config, $g;
1747
	if ($g['platform'] == 'jail' || !$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1748
		return;
1749
	if(isset($config['system']['developerspew'])) {
1750
		$mt = microtime();
1751
		echo "setup_wireless_olsr($interface) being called $mt\n";
1752
	}
1753
	conf_mount_rw();
1754
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1755
		$olsr_enable = $olsrd['enable'];
1756
		if($olsr_enable <> "on") {
1757
			if (is_process_running("olsrd"))
1758
				mwexec("/usr/bin/killall olsrd", true);
1759
			return;
1760
		}
1761
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1762

    
1763
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1764
			$enableannounce .= "\nHna4\n";
1765
			$enableannounce .= "{\n";
1766
		if($olsrd['announcedynamicroute'])
1767
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1768
		if($olsrd['enableannounce'] == "on")
1769
			$enableannounce .= "0.0.0.0 0.0.0.0";
1770
			$enableannounce .= "\n}\n";
1771
		} else {
1772
			$enableannounce = "";
1773
		}
1774

    
1775
		$olsr .= <<<EODA
1776
#
1777
# olsr.org OLSR daemon config file
1778
#
1779
# Lines starting with a # are discarded
1780
#
1781
# This file was generated by setup_wireless_olsr() in services.inc
1782
#
1783

    
1784
# This file is an example of a typical
1785
# configuration for a mostly static
1786
# network(regarding mobility) using
1787
# the LQ extention
1788

    
1789
# Debug level(0-9)
1790
# If set to 0 the daemon runs in the background
1791

    
1792
DebugLevel	2
1793

    
1794
# IP version to use (4 or 6)
1795

    
1796
IpVersion	4
1797

    
1798
# Clear the screen each time the internal state changes
1799

    
1800
ClearScreen     yes
1801

    
1802
{$enableannounce}
1803

    
1804
# Should olsrd keep on running even if there are
1805
# no interfaces available? This is a good idea
1806
# for a PCMCIA/USB hotswap environment.
1807
# "yes" OR "no"
1808

    
1809
AllowNoInt	yes
1810

    
1811
# TOS(type of service) value for
1812
# the IP header of control traffic.
1813
# If not set it will default to 16
1814

    
1815
#TosValue	16
1816

    
1817
# The fixed willingness to use(0-7)
1818
# If not set willingness will be calculated
1819
# dynamically based on battery/power status
1820
# if such information is available
1821

    
1822
#Willingness    	4
1823

    
1824
# Allow processes like the GUI front-end
1825
# to connect to the daemon.
1826

    
1827
IpcConnect
1828
{
1829
     # Determines how many simultaneously
1830
     # IPC connections that will be allowed
1831
     # Setting this to 0 disables IPC
1832

    
1833
     MaxConnections  0
1834

    
1835
     # By default only 127.0.0.1 is allowed
1836
     # to connect. Here allowed hosts can
1837
     # be added
1838

    
1839
     Host            127.0.0.1
1840
     #Host            10.0.0.5
1841

    
1842
     # You can also specify entire net-ranges
1843
     # that are allowed to connect. Multiple
1844
     # entries are allowed
1845

    
1846
     #Net             192.168.1.0 255.255.255.0
1847
}
1848

    
1849
# Wether to use hysteresis or not
1850
# Hysteresis adds more robustness to the
1851
# link sensing but delays neighbor registration.
1852
# Used by default. 'yes' or 'no'
1853

    
1854
UseHysteresis	no
1855

    
1856
# Hysteresis parameters
1857
# Do not alter these unless you know
1858
# what you are doing!
1859
# Set to auto by default. Allowed
1860
# values are floating point values
1861
# in the interval 0,1
1862
# THR_LOW must always be lower than
1863
# THR_HIGH.
1864

    
1865
#HystScaling	0.50
1866
#HystThrHigh	0.80
1867
#HystThrLow	0.30
1868

    
1869

    
1870
# Link quality level
1871
# 0 = do not use link quality
1872
# 1 = use link quality for MPR selection
1873
# 2 = use link quality for MPR selection and routing
1874
# Defaults to 0
1875

    
1876
LinkQualityLevel	{$olsrd['enablelqe']}
1877

    
1878
# Link quality window size
1879
# Defaults to 10
1880

    
1881
LinkQualityWinSize	10
1882

    
1883
# Polling rate in seconds(float).
1884
# Default value 0.05 sec
1885

    
1886
Pollrate	0.05
1887

    
1888

    
1889
# TC redundancy
1890
# Specifies how much neighbor info should
1891
# be sent in TC messages
1892
# Possible values are:
1893
# 0 - only send MPR selectors
1894
# 1 - send MPR selectors and MPRs
1895
# 2 - send all neighbors
1896
#
1897
# defaults to 0
1898

    
1899
TcRedundancy	2
1900

    
1901
#
1902
# MPR coverage
1903
# Specifies how many MPRs a node should
1904
# try select to reach every 2 hop neighbor
1905
#
1906
# Can be set to any integer >0
1907
#
1908
# defaults to 1
1909

    
1910
MprCoverage	3
1911

    
1912
# Example plugin entry with parameters:
1913

    
1914
EODA;
1915

    
1916
if($olsrd['enablehttpinfo'] == "on") {
1917
	$olsr .= <<<EODB
1918

    
1919
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1920
{
1921
    PlParam     "port"   "{$olsrd['port']}"
1922
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1923
}
1924

    
1925
EODB;
1926

    
1927
}
1928

    
1929
if($olsrd['enabledsecure'] == "on") {
1930
	$olsr .= <<<EODC
1931

    
1932
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1933
{
1934
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1935
}
1936

    
1937
EODC;
1938

    
1939
}
1940

    
1941
if($olsrd['enabledyngw'] == "on") {
1942

    
1943
	/* unset default route, olsr auto negotiates */
1944
	mwexec("/sbin/route delete default");
1945

    
1946
	$olsr .= <<<EODE
1947

    
1948
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1949
{
1950
    # how often to look for a inet gw, in seconds
1951
    # defaults to 5 secs, if commented out
1952
    PlParam     "Interval"   "{$olsrd['polling']}"
1953

    
1954
    # if one or more IPv4 addresses are given, do a ping on these in
1955
    # descending order to validate that there is not only an entry in
1956
    # routing table, but also a real internet connection. If any of
1957
    # these addresses could be pinged successfully, the test was
1958
    # succesful, i.e. if the ping on the 1st address was successful,the
1959
    # 2nd won't be pinged
1960
    PlParam     "Ping"       "{$olsrd['ping']}"
1961
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1962
}
1963

    
1964
EODE;
1965

    
1966
}
1967

    
1968
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1969
	$interfaces = explode(',', $conf['iface_array']);
1970
	foreach($interfaces as $interface) {
1971
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1972
$olsr .= <<<EODAD
1973
Interface "{$realinterface}"
1974
{
1975

    
1976
    # Hello interval in seconds(float)
1977
    HelloInterval    2.0
1978

    
1979
    # HELLO validity time
1980
    HelloValidityTime	20.0
1981

    
1982
    # TC interval in seconds(float)
1983
    TcInterval        5.0
1984

    
1985
    # TC validity time
1986
    TcValidityTime	30.0
1987

    
1988
    # MID interval in seconds(float)
1989
    MidInterval	5.0
1990

    
1991
    # MID validity time
1992
    MidValidityTime	30.0
1993

    
1994
    # HNA interval in seconds(float)
1995
    HnaInterval	5.0
1996

    
1997
    # HNA validity time
1998
    HnaValidityTime 	30.0
1999

    
2000
    # When multiple links exist between hosts
2001
    # the weight of interface is used to determine
2002
    # the link to use. Normally the weight is
2003
    # automatically calculated by olsrd based
2004
    # on the characteristics of the interface,
2005
    # but here you can specify a fixed value.
2006
    # Olsrd will choose links with the lowest value.
2007

    
2008
    # Weight 0
2009

    
2010

    
2011
}
2012

    
2013
EODAD;
2014

    
2015
	}
2016
	break;
2017
}
2018
		fwrite($fd, $olsr);
2019
		fclose($fd);
2020
	}
2021

    
2022
	if (is_process_running("olsrd"))
2023
		mwexec("/usr/bin/killall olsrd", true);
2024

    
2025
	sleep(2);
2026

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

    
2029
	conf_mount_ro();
2030
}
2031

    
2032
/* configure cron service */
2033
function configure_cron() {
2034
	global $g, $config;
2035

    
2036
	conf_mount_rw();
2037
	/* preserve existing crontab entries */
2038
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2039

    
2040
	for ($i = 0; $i < count($crontab_contents); $i++) {
2041
		$cron_item =& $crontab_contents[$i];
2042
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
2043
			array_splice($crontab_contents, $i - 1);
2044
			break;
2045
		}
2046
	}
2047
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
2048

    
2049

    
2050
	if (is_array($config['cron']['item'])) {
2051
		$crontab_contents .= "#\n";
2052
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2053
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
2054
		$crontab_contents .= "#\n";
2055

    
2056
		foreach ($config['cron']['item'] as $item) {
2057
			$crontab_contents .= "\n{$item['minute']}\t";
2058
			$crontab_contents .= "{$item['hour']}\t";
2059
			$crontab_contents .= "{$item['mday']}\t";
2060
			$crontab_contents .= "{$item['month']}\t";
2061
			$crontab_contents .= "{$item['wday']}\t";
2062
			$crontab_contents .= "{$item['who']}\t";
2063
			$crontab_contents .= "{$item['command']}";
2064
		}
2065

    
2066
		$crontab_contents .= "\n#\n";
2067
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2068
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2069
		$crontab_contents .= "#\n\n";
2070
	}
2071

    
2072
	/* please maintain the newline at the end of file */
2073
	file_put_contents("/etc/crontab", $crontab_contents);
2074

    
2075
	/* do a HUP kill to force sync changes */
2076
	exec('/bin/pkill -HUP cron');
2077

    
2078
	conf_mount_ro();
2079
}
2080

    
2081
function upnp_action ($action) {
2082
	global $g, $config;
2083
	switch($action) {
2084
		case "start":
2085
			if (file_exists('/var/etc/miniupnpd.conf')) {
2086
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
2087
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
2088
			}
2089
			break;
2090
		case "stop":
2091
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
2092
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
2093
				mwexec('killall miniupnpd 2>/dev/null', true);
2094
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
2095
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
2096
			break;
2097
		case "restart":
2098
			upnp_action('stop');
2099
			upnp_action('start');
2100
			break;
2101
	}
2102
}
2103

    
2104
function upnp_start() {
2105
	global $config;
2106

    
2107
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2108
		return;
2109

    
2110
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2111
		echo gettext("Starting UPnP service... ");
2112
		require_once('/usr/local/pkg/miniupnpd.inc');
2113
		sync_package_miniupnpd();
2114
		echo "done.\n";
2115
	}
2116
}
2117

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

    
2121
	$is_installed = false;
2122

    
2123
	if(!$config['cron']['item'])
2124
		return;
2125

    
2126
	$x=0;
2127
	foreach($config['cron']['item'] as $item) {
2128
		if(strstr($item['command'], $command)) {
2129
			$is_installed = true;
2130
			break;
2131
		}
2132
		$x++;
2133
	}
2134

    
2135
	if($active) {
2136
		$cron_item = array();
2137
		$cron_item['minute'] = $minute;
2138
		$cron_item['hour'] = $hour;
2139
		$cron_item['mday'] = $monthday;
2140
		$cron_item['month'] = $month;
2141
		$cron_item['wday'] = $weekday;
2142
		$cron_item['who'] = $who;
2143
		$cron_item['command'] = $command;
2144
		if(!$is_installed) {
2145
			$config['cron']['item'][] = $cron_item;
2146
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
2147
		} else {
2148
			$config['cron']['item'][$x] = $cron_item;
2149
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
2150
		}
2151
	} else {
2152
		if(($is_installed == true) && ($x > 0)) {
2153
			unset($config['cron']['item'][$x]);
2154
			write_config(sprintf(gettext("Remvoed cron job for %s"), $command));
2155
		}
2156
	}
2157
	configure_cron();
2158
}
2159

    
2160
?>
(47-47/65)