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_MODULE:	utils
40
*/
41

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

    
46

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
351
	$dhcpdconf = <<<EOD
352

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

    
365
EOD;
366

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

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

    
373
	$dhcpdifs = array();
374

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

    
381
		interfaces_staticarp_configure($dhcpif);
382

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

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

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

    
437
	$dhcpnum = 0;
438

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

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

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

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

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

    
457
		$dnscfg = "";
458

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
571
EOD;
572

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

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

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

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

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

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

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

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

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

    
611

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

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

    
622
	return 0;
623
}
624

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
739
	$dhcpdv6conf = <<<EOD
740

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

    
753
EOD;
754

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

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

    
761
	$dhcpdv6ifs = array();
762

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

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

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

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

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

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

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

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

    
839
		$dnscfgv6 = "";
840

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

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

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

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

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

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

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

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

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

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

    
897
EOD;
898

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

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

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

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

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

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

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

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

    
955
EOD;
956

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

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

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

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

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

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

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

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

    
1004

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

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

    
1016
	return 0;
1017
}
1018

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

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

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

    
1028
        $iflist = get_configured_interface_list();
1029

    
1030
        $igmpconf = <<<EOD
1031

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

    
1037
EOD;
1038

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

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

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

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

    
1072
        return 0;
1073
}
1074

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

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

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

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

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

    
1098
	$iflist = get_configured_interface_list();
1099

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

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

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

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

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

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

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

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

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

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

    
1188
	return 0;
1189
}
1190

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

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

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

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

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

    
1214
	$iflist = get_configured_interface_list();
1215

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

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

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

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

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

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

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

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

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

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

    
1304
	return 0;
1305
}
1306

    
1307
function services_dyndns_configure_client($conf) {
1308

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

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

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

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

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

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

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

    
1348
			services_dyndns_configure_client($dyndns);
1349

    
1350
			sleep(1);
1351
		}
1352

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

    
1357
	return 0;
1358
}
1359

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

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

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

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

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

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

    
1384
		$args = "";
1385

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

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

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

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

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

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

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

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

    
1426
	return $return;
1427
}
1428

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

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

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

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

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

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

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

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

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

    
1472
	return $return;
1473
}
1474

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

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

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

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

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

    
1500

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

    
1506
EOD;
1507

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

    
1514
EOD;
1515
		}
1516
*/
1517

    
1518

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

    
1526

    
1527
EOD;
1528
		}
1529

    
1530

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

    
1538
EOD;
1539

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

    
1545
EOD;
1546
		}
1547
*/
1548

    
1549

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

    
1556
EOD;
1557
		}
1558

    
1559

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

    
1563
EOD;
1564

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

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

    
1584
EOD;
1585

    
1586
		}
1587

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

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

    
1597
snmpEnableAuthenTraps = 2
1598

    
1599
EOD;
1600

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

    
1606
EOD;
1607
		    }
1608

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

    
1615
EOD;
1616
		    }
1617

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

    
1622
EOD;
1623
		    }
1624

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

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

    
1636

    
1637
EOD;
1638
		    }
1639
		}
1640

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

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

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

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

    
1656
	return 0;
1657
}
1658

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1741
	return 0;
1742
}
1743

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

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

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

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

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

    
1791
DebugLevel	2
1792

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

    
1795
IpVersion	4
1796

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

    
1799
ClearScreen     yes
1800

    
1801
{$enableannounce}
1802

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

    
1808
AllowNoInt	yes
1809

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

    
1814
#TosValue	16
1815

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

    
1821
#Willingness    	4
1822

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

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

    
1832
     MaxConnections  0
1833

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

    
1838
     Host            127.0.0.1
1839
     #Host            10.0.0.5
1840

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

    
1845
     #Net             192.168.1.0 255.255.255.0
1846
}
1847

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

    
1853
UseHysteresis	no
1854

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

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

    
1868

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

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

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

    
1880
LinkQualityWinSize	10
1881

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

    
1885
Pollrate	0.05
1886

    
1887

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

    
1898
TcRedundancy	2
1899

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

    
1909
MprCoverage	3
1910

    
1911
# Example plugin entry with parameters:
1912

    
1913
EODA;
1914

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

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

    
1924
EODB;
1925

    
1926
}
1927

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

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

    
1936
EODC;
1937

    
1938
}
1939

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

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

    
1945
	$olsr .= <<<EODE
1946

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

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

    
1963
EODE;
1964

    
1965
}
1966

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

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

    
1978
    # HELLO validity time
1979
    HelloValidityTime	20.0
1980

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

    
1984
    # TC validity time
1985
    TcValidityTime	30.0
1986

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

    
1990
    # MID validity time
1991
    MidValidityTime	30.0
1992

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

    
1996
    # HNA validity time
1997
    HnaValidityTime 	30.0
1998

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

    
2007
    # Weight 0
2008

    
2009

    
2010
}
2011

    
2012
EODAD;
2013

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

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

    
2024
	sleep(2);
2025

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

    
2028
	conf_mount_ro();
2029
}
2030

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

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

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

    
2048

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

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

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

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

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

    
2077
	conf_mount_ro();
2078
}
2079

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

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

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

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

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

    
2120
	$is_installed = false;
2121

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

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

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

    
2159
?>
(47-47/65)