Project

General

Profile

Download (58.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
	if(!trim($status))
268
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
269
	fclose($fd);
270
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
271

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

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

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

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

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

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

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

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

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

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

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

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

    
350
	$dhcpdconf = <<<EOD
351

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

    
364
EOD;
365

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

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

    
372
	$dhcpdifs = array();
373

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

    
380
		interfaces_staticarp_configure($dhcpif);
381

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

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

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

    
436
	$dhcpnum = 0;
437

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

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

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

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

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

    
456
		$dnscfg = "";
457

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
570
EOD;
571

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

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

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

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

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

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

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

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

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

    
610

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

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

    
621
	return 0;
622
}
623

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

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

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

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

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

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

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

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

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

    
717
		}
718
	}
719

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

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

    
736
	$dhcpdv6conf = <<<EOD
737

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

    
750
EOD;
751

    
752
	if(!isset($dhcpv6ifconf['disableauthoritative']))
753
		$dhcpdv6conf .= "authoritative;\n";
754

    
755
	if(isset($dhcpv6ifconf['alwaysbroadcast']))
756
		$dhcpdv6conf .= "always-broadcast on\n";
757

    
758
	$dhcpdv6ifs = array();
759

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

    
766
		if (!isset($dhcpv6ifconf['enable']))
767
			continue;
768

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

    
815
EOPP;
816
		$dhcpv6num++;
817
		}
818
	}
819

    
820
	$dhcpv6num = 0;
821
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
822

    
823
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
824

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

    
832
		if($is_olsr_enabled == true)
833
			if($dhcpv6ifconf['netmask'])
834
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
835

    
836
		$dnscfgv6 = "";
837

    
838
		if ($dhcpv6ifconf['domain']) {
839
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
840
		}
841

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

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

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

    
868
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
869
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
870

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

    
879
		if($dhcpv6ifconf['failover_peerip'] <> "")
880
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
881

    
882
		if (isset($dhcpv6ifconf['denyunknown']))
883
		   $dhcpdv6conf .= "		deny unknown-clients;\n";
884

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

    
890
		$dhcpdv6conf .= <<<EOD
891
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
892
$dnscfgv6
893

    
894
EOD;
895

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

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

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

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

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

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

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

    
949
		$dhcpdv6conf .= <<<EOD
950
}
951

    
952
EOD;
953

    
954
		/* add static mappings */
955
		/* Needs to use DUID */
956
		if (is_array($dhcpv6ifconf['staticmap'])) {
957

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

    
964
EOD;
965
				if ($sm['ipaddrv6'])
966
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
967

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

    
976
				if ($sm['rootpath'])
977
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
978

    
979
				$dhcpdv6conf .= "}\n";
980
				$i++;
981
			}
982
		}
983

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

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

    
1001

    
1002
	/* fire up dhcpd in a chroot */
1003
	if(count($dhcpdv6ifs) > 0) {
1004
		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 " .
1005
			join(" ", $dhcpdv6ifs));
1006
	}
1007

    
1008
	if ($g['booting']) {
1009
		print gettext("done.") . "\n";
1010
	}
1011

    
1012
	return 0;
1013
}
1014

    
1015
function services_igmpproxy_configure() {
1016
        global $config, $g;
1017

    
1018
        /* kill any running igmpproxy */
1019
        killbyname("igmpproxy");
1020

    
1021
	if (!is_array($config['igmpproxy']['igmpentry']))
1022
		return 1;
1023

    
1024
        $iflist = get_configured_interface_list();
1025

    
1026
        $igmpconf = <<<EOD
1027

    
1028
##------------------------------------------------------
1029
## Enable Quickleave mode (Sends Leave instantly)
1030
##------------------------------------------------------
1031
quickleave
1032

    
1033
EOD;
1034

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

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

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

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

    
1068
        return 0;
1069
}
1070

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

    
1080
	/* kill any running dhcrelay */
1081
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1082

    
1083
	$dhcrelaycfg =& $config['dhcrelay'];
1084

    
1085
	/* DHCPRelay enabled on any interfaces? */
1086
	if (!isset($dhcrelaycfg['enable']))
1087
		return 0;
1088

    
1089
	if ($g['booting'])
1090
		echo gettext("Starting DHCP relay service...");
1091
	else
1092
		sleep(1);
1093

    
1094
	$iflist = get_configured_interface_list();
1095

    
1096
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1097
	foreach ($dhcifaces as $dhcrelayif) {
1098
		if (!isset($iflist[$dhcrelayif]) ||
1099
			link_interface_to_bridge($dhcrelayif))
1100
			continue;
1101

    
1102
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
1103
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1104
	}
1105

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

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

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

    
1165
		if (!empty($destif))
1166
			$dhcrelayifs[] = $destif;
1167
	}
1168
	$dhcrelayifs = array_unique($dhcrelayifs);
1169

    
1170
	/* fire up dhcrelay */
1171
	if (empty($dhcrelayifs)) {
1172
		log_error("No suitable interface found for running dhcrelay!");
1173
		return; /* XXX */
1174
	}
1175

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

    
1178
	if (isset($dhcrelaycfg['agentoption']))
1179
		$cmd .=  " -a -m replace";
1180

    
1181
	$cmd .= " " . implode(" ", $srvips);
1182
	mwexec($cmd);
1183

    
1184
	return 0;
1185
}
1186

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

    
1196
	/* kill any running dhcrelay */
1197
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1198

    
1199
	$dhcrelaycfg =& $config['dhcrelay6'];
1200

    
1201
	/* DHCPv6 Relay enabled on any interfaces? */
1202
	if (!isset($dhcrelaycfg['enable']))
1203
		return 0;
1204

    
1205
	if ($g['booting'])
1206
		echo gettext("Starting DHCPv6 relay service...");
1207
	else
1208
		sleep(1);
1209

    
1210
	$iflist = get_configured_interface_list();
1211

    
1212
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1213
	foreach ($dhcifaces as $dhcrelayif) {
1214
		if (!isset($iflist[$dhcrelayif]) ||
1215
			link_interface_to_bridge($dhcrelayif))
1216
			continue;
1217

    
1218
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif)))
1219
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1220
	}
1221

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

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

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

    
1281
		if (!empty($destif))
1282
			$dhcrelayifs[] = $destif;
1283
	}
1284
	$dhcrelayifs = array_unique($dhcrelayifs);
1285

    
1286
	/* fire up dhcrelay */
1287
	if (empty($dhcrelayifs)) {
1288
		log_error("No suitable interface found for running dhcrelay -6!");
1289
		return; /* XXX */
1290
	}
1291

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

    
1294
	if (isset($dhcrelaycfg['agentoption']))
1295
		$cmd .=  " -a -m replace";
1296

    
1297
	$cmd .= " " . implode(" ", $srvips);
1298
	mwexec($cmd);
1299

    
1300
	return 0;
1301
}
1302

    
1303
function services_dyndns_configure_client($conf) {
1304

    
1305
	if (!isset($conf['enable']))
1306
		return;
1307

    
1308
	/* load up the dyndns.class */
1309
	require_once("dyndns.class");
1310

    
1311
	$dns = new updatedns($dnsService = $conf['type'],
1312
		$dnsHost = $conf['host'],
1313
		$dnsUser = $conf['username'],
1314
		$dnsPass = $conf['password'],
1315
		$dnsWilcard = $conf['wildcard'],
1316
		$dnsMX = $conf['mx'],
1317
		$dnsIf = "{$conf['interface']}",
1318
		$dnsBackMX = NULL,
1319
		$dnsServer = NULL,
1320
		$dnsPort = NULL,
1321
		$dnsUpdateURL = NULL,
1322
		$forceUpdate = $conf['force']);
1323
}
1324

    
1325
function services_dyndns_configure($int = "") {
1326
	global $config, $g;
1327
	if(isset($config['system']['developerspew'])) {
1328
		$mt = microtime();
1329
		echo "services_dyndns_configure() being called $mt\n";
1330
	}
1331

    
1332
	$dyndnscfg = $config['dyndnses']['dyndns'];
1333

    
1334
	if (is_array($dyndnscfg)) {
1335
		if ($g['booting'])
1336
			echo gettext("Starting DynDNS clients...");
1337

    
1338
		foreach ($dyndnscfg as $dyndns) {
1339
			if (!empty($int) && $int != $dyndns['interface'])
1340
				continue;
1341

    
1342
			services_dyndns_configure_client($dyndns);
1343

    
1344
			sleep(1);
1345
		}
1346

    
1347
		if ($g['booting'])
1348
			echo gettext("done.") . "\n";
1349
	}
1350

    
1351
	return 0;
1352
}
1353

    
1354
function services_dnsmasq_configure() {
1355
	global $config, $g;
1356
	$return = 0;
1357

    
1358
	if(isset($config['system']['developerspew'])) {
1359
		$mt = microtime();
1360
		echo "services_dnsmasq_configure() being called $mt\n";
1361
	}
1362

    
1363
	/* kill any running dnsmasq */
1364
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
1365
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1366

    
1367
	if (isset($config['dnsmasq']['enable'])) {
1368

    
1369
		if ($g['booting'])
1370
			echo gettext("Starting DNS forwarder...");
1371
		else
1372
			sleep(1);
1373

    
1374
		/* generate hosts file */
1375
		if(system_hosts_generate()!=0)
1376
			$return = 1;
1377

    
1378
		$args = "";
1379

    
1380
		if (isset($config['dnsmasq']['regdhcp'])) {
1381
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1382
		}
1383

    
1384
		/* Setup forwarded domains */
1385
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1386
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1387
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1388
			}
1389
		}
1390

    
1391
		/* Allow DNS Rebind for forwarded domains */
1392
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1393
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1394
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1395
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1396
				}
1397
			}
1398
		}
1399

    
1400
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1401
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1402

    
1403
		if ($config['dnsmasq']['custom_options']) {
1404
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1405
				$args .= " --$c";
1406
		}
1407

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

    
1411
		if ($g['booting'])
1412
			echo gettext("done.") . "\n";
1413
	}
1414

    
1415
	if (!$g['booting']) {
1416
		if(services_dhcpd_configure()!=0)
1417
			$return = 1;
1418
	}
1419

    
1420
	return $return;
1421
}
1422

    
1423
function services_unbound_configure() {
1424
	global $config, $g;
1425
	$return = 0;
1426

    
1427
	if(isset($config['system']['developerspew'])) {
1428
		$mt = microtime();
1429
		echo "services_unbound_configure() being called $mt\n";
1430
	}
1431

    
1432
	/* kill any running unbound */
1433
	sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1434

    
1435
	if (isset($config['unbound']['enable'])) {
1436

    
1437
		if ($g['booting'])
1438
			echo "Starting Unbound DNS...";
1439
		else
1440
			sleep(1);
1441

    
1442
		/* generate Unbound config file */
1443
		if(unbound_generate_config()!=0) {
1444
			log_error("Problem generating Unbound configuration.");
1445
			$return = 1;
1446
		}
1447

    
1448
		/* run Unbound */
1449
		mwexec("/usr/local/sbin/unbound");
1450

    
1451
		if ($g['booting'])
1452
			echo "done.\n";
1453
	}
1454

    
1455
	return $return;
1456
}
1457

    
1458
function services_snmpd_configure() {
1459
	global $config, $g;
1460
	if(isset($config['system']['developerspew'])) {
1461
		$mt = microtime();
1462
		echo "services_snmpd_configure() being called $mt\n";
1463
	}
1464

    
1465
	/* kill any running snmpd */
1466
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1467
	sleep(2);
1468
	if(is_process_running("bsnmpd"))
1469
		mwexec("/usr/bin/killall bsnmpd", true);
1470

    
1471
	if (isset($config['snmpd']['enable'])) {
1472

    
1473
		if ($g['booting'])
1474
			echo gettext("Starting SNMP daemon... ");
1475

    
1476
		/* generate snmpd.conf */
1477
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1478
		if (!$fd) {
1479
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1480
			return 1;
1481
		}
1482

    
1483

    
1484
		$snmpdconf = <<<EOD
1485
location := "{$config['snmpd']['syslocation']}"
1486
contact := "{$config['snmpd']['syscontact']}"
1487
read := "{$config['snmpd']['rocommunity']}"
1488

    
1489
EOD;
1490

    
1491
/* No docs on what write strings do there for disable for now.
1492
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1493
		    $snmpdconf .= <<<EOD
1494
# write string
1495
write := "{$config['snmpd']['rwcommunity']}"
1496

    
1497
EOD;
1498
		}
1499
*/
1500

    
1501

    
1502
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1503
		    $snmpdconf .= <<<EOD
1504
# SNMP Trap support.
1505
traphost := {$config['snmpd']['trapserver']}
1506
trapport := {$config['snmpd']['trapserverport']}
1507
trap := "{$config['snmpd']['trapstring']}"
1508

    
1509

    
1510
EOD;
1511
		}
1512

    
1513

    
1514
		$snmpdconf .= <<<EOD
1515
system := 1     # pfSense
1516
%snmpd
1517
begemotSnmpdDebugDumpPdus       = 2
1518
begemotSnmpdDebugSyslogPri      = 7
1519
begemotSnmpdCommunityString.0.1 = $(read)
1520

    
1521
EOD;
1522

    
1523
/* No docs on what write strings do there for disable for now.
1524
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1525
		    $snmpdconf .= <<<EOD
1526
begemotSnmpdCommunityString.0.2 = $(write)
1527

    
1528
EOD;
1529
		}
1530
*/
1531

    
1532

    
1533
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1534
		    $snmpdconf .= <<<EOD
1535
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1536
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1537
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1538

    
1539
EOD;
1540
		}
1541

    
1542

    
1543
		$snmpdconf .= <<<EOD
1544
begemotSnmpdCommunityDisable    = 1
1545

    
1546
EOD;
1547

    
1548
		if (isset($config['snmpd']['bindlan'])) {
1549
			$config['snmpd']['bindip'] = 'lan';
1550
			unset($config['snmpd']['bindlan']);
1551
		}
1552
		$bind_to_ip = "0.0.0.0";
1553
		if(isset($config['snmpd']['bindip'])) {
1554
			if (is_ipaddr($config['snmpd']['bindip'])) {
1555
				$bind_to_ip = $config['snmpd']['bindip'];
1556
			} else {
1557
				$if = get_real_interface($config['snmpd']['bindip']);
1558
				if (does_interface_exist($if))
1559
					$bind_to_ip = find_interface_ip($if);
1560
			}
1561
		}
1562

    
1563
		if(is_port( $config['snmpd']['pollport'] )) {
1564
		    $snmpdconf .= <<<EOD
1565
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1566

    
1567
EOD;
1568

    
1569
		}
1570

    
1571
		$snmpdconf .= <<<EOD
1572
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1573
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1574

    
1575
# These are bsnmp macros not php vars.
1576
sysContact      = $(contact)
1577
sysLocation     = $(location)
1578
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1579

    
1580
snmpEnableAuthenTraps = 2
1581

    
1582
EOD;
1583

    
1584
		if (is_array( $config['snmpd']['modules'] )) {
1585
		    if(isset($config['snmpd']['modules']['mibii'])) {
1586
			$snmpdconf .= <<<EOD
1587
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1588

    
1589
EOD;
1590
		    }
1591

    
1592
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1593
			$snmpdconf .= <<<EOD
1594
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1595
%netgraph
1596
begemotNgControlNodeName = "snmpd"
1597

    
1598
EOD;
1599
		    }
1600

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

    
1605
EOD;
1606
		    }
1607

    
1608
		    if(isset($config['snmpd']['modules']['hostres'])) {
1609
			$snmpdconf .= <<<EOD
1610
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1611

    
1612
EOD;
1613
		    }
1614
		    if(isset($config['snmpd']['modules']['bridge'])) {
1615
			$snmpdconf .= <<<EOD
1616
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1617
# config must end with blank line
1618

    
1619

    
1620
EOD;
1621
		    }
1622
		}
1623

    
1624
		fwrite($fd, $snmpdconf);
1625
		fclose($fd);
1626

    
1627
		if (isset($config['snmpd']['bindlan'])) {
1628
			$bindlan = "";
1629
		}
1630

    
1631
		/* run bsnmpd */
1632
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1633
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1634

    
1635
		if ($g['booting'])
1636
			echo gettext("done.") . "\n";
1637
	}
1638

    
1639
	return 0;
1640
}
1641

    
1642
function services_dnsupdate_process($int = "") {
1643
	global $config, $g;
1644
	if(isset($config['system']['developerspew'])) {
1645
		$mt = microtime();
1646
		echo "services_dnsupdate_process() being called $mt\n";
1647
	}
1648

    
1649
	/* Dynamic DNS updating active? */
1650
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1651
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1652
			if (!isset($dnsupdate['enable']))
1653
				continue;
1654
			if (!empty($int) && $int != $dnsupdate['interface'])
1655
				continue;
1656

    
1657
			/* determine interface name */
1658
			$if = get_real_interface($dnsupdate['interface']);
1659
			$wanip = get_interface_ip($dnsupdate['interface']);
1660
			if ($wanip) {
1661

    
1662
				$keyname = $dnsupdate['keyname'];
1663
				/* trailing dot */
1664
				if (substr($keyname, -1) != ".")
1665
					$keyname .= ".";
1666

    
1667
				$hostname = $dnsupdate['host'];
1668
				/* trailing dot */
1669
				if (substr($hostname, -1) != ".")
1670
					$hostname .= ".";
1671

    
1672
				/* write private key file
1673
				   this is dumb - public and private keys are the same for HMAC-MD5,
1674
				   but nsupdate insists on having both */
1675
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1676
				$privkey = <<<EOD
1677
Private-key-format: v1.2
1678
Algorithm: 157 (HMAC)
1679
Key: {$dnsupdate['keydata']}
1680

    
1681
EOD;
1682
				fwrite($fd, $privkey);
1683
				fclose($fd);
1684

    
1685
				/* write public key file */
1686
				if ($dnsupdate['keytype'] == "zone") {
1687
					$flags = 257;
1688
					$proto = 3;
1689
				} else if ($dnsupdate['keytype'] == "host") {
1690
					$flags = 513;
1691
					$proto = 3;
1692
				} else if ($dnsupdate['keytype'] == "user") {
1693
					$flags = 0;
1694
					$proto = 2;
1695
				}
1696

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

    
1701
				/* generate update instructions */
1702
				$upinst = "";
1703
				if (!empty($dnsupdate['server']))
1704
					$upinst .= "server {$dnsupdate['server']}\n";
1705
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1706
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1707
				$upinst .= "\n";	/* mind that trailing newline! */
1708

    
1709
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1710
				fwrite($fd, $upinst);
1711
				fclose($fd);
1712

    
1713
				/* invoke nsupdate */
1714
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1715
				if (isset($dnsupdate['usetcp']))
1716
					$cmd .= " -v";
1717
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1718

    
1719
				mwexec_bg($cmd);
1720
			}
1721
		}
1722
	}
1723

    
1724
	return 0;
1725
}
1726

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

    
1745
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1746
			$enableannounce .= "\nHna4\n";
1747
			$enableannounce .= "{\n";
1748
		if($olsrd['announcedynamicroute'])
1749
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1750
		if($olsrd['enableannounce'] == "on")
1751
			$enableannounce .= "0.0.0.0 0.0.0.0";
1752
			$enableannounce .= "\n}\n";
1753
		} else {
1754
			$enableannounce = "";
1755
		}
1756

    
1757
		$olsr .= <<<EODA
1758
#
1759
# olsr.org OLSR daemon config file
1760
#
1761
# Lines starting with a # are discarded
1762
#
1763
# This file was generated by setup_wireless_olsr() in services.inc
1764
#
1765

    
1766
# This file is an example of a typical
1767
# configuration for a mostly static
1768
# network(regarding mobility) using
1769
# the LQ extention
1770

    
1771
# Debug level(0-9)
1772
# If set to 0 the daemon runs in the background
1773

    
1774
DebugLevel	2
1775

    
1776
# IP version to use (4 or 6)
1777

    
1778
IpVersion	4
1779

    
1780
# Clear the screen each time the internal state changes
1781

    
1782
ClearScreen     yes
1783

    
1784
{$enableannounce}
1785

    
1786
# Should olsrd keep on running even if there are
1787
# no interfaces available? This is a good idea
1788
# for a PCMCIA/USB hotswap environment.
1789
# "yes" OR "no"
1790

    
1791
AllowNoInt	yes
1792

    
1793
# TOS(type of service) value for
1794
# the IP header of control traffic.
1795
# If not set it will default to 16
1796

    
1797
#TosValue	16
1798

    
1799
# The fixed willingness to use(0-7)
1800
# If not set willingness will be calculated
1801
# dynamically based on battery/power status
1802
# if such information is available
1803

    
1804
#Willingness    	4
1805

    
1806
# Allow processes like the GUI front-end
1807
# to connect to the daemon.
1808

    
1809
IpcConnect
1810
{
1811
     # Determines how many simultaneously
1812
     # IPC connections that will be allowed
1813
     # Setting this to 0 disables IPC
1814

    
1815
     MaxConnections  0
1816

    
1817
     # By default only 127.0.0.1 is allowed
1818
     # to connect. Here allowed hosts can
1819
     # be added
1820

    
1821
     Host            127.0.0.1
1822
     #Host            10.0.0.5
1823

    
1824
     # You can also specify entire net-ranges
1825
     # that are allowed to connect. Multiple
1826
     # entries are allowed
1827

    
1828
     #Net             192.168.1.0 255.255.255.0
1829
}
1830

    
1831
# Wether to use hysteresis or not
1832
# Hysteresis adds more robustness to the
1833
# link sensing but delays neighbor registration.
1834
# Used by default. 'yes' or 'no'
1835

    
1836
UseHysteresis	no
1837

    
1838
# Hysteresis parameters
1839
# Do not alter these unless you know
1840
# what you are doing!
1841
# Set to auto by default. Allowed
1842
# values are floating point values
1843
# in the interval 0,1
1844
# THR_LOW must always be lower than
1845
# THR_HIGH.
1846

    
1847
#HystScaling	0.50
1848
#HystThrHigh	0.80
1849
#HystThrLow	0.30
1850

    
1851

    
1852
# Link quality level
1853
# 0 = do not use link quality
1854
# 1 = use link quality for MPR selection
1855
# 2 = use link quality for MPR selection and routing
1856
# Defaults to 0
1857

    
1858
LinkQualityLevel	{$olsrd['enablelqe']}
1859

    
1860
# Link quality window size
1861
# Defaults to 10
1862

    
1863
LinkQualityWinSize	10
1864

    
1865
# Polling rate in seconds(float).
1866
# Default value 0.05 sec
1867

    
1868
Pollrate	0.05
1869

    
1870

    
1871
# TC redundancy
1872
# Specifies how much neighbor info should
1873
# be sent in TC messages
1874
# Possible values are:
1875
# 0 - only send MPR selectors
1876
# 1 - send MPR selectors and MPRs
1877
# 2 - send all neighbors
1878
#
1879
# defaults to 0
1880

    
1881
TcRedundancy	2
1882

    
1883
#
1884
# MPR coverage
1885
# Specifies how many MPRs a node should
1886
# try select to reach every 2 hop neighbor
1887
#
1888
# Can be set to any integer >0
1889
#
1890
# defaults to 1
1891

    
1892
MprCoverage	3
1893

    
1894
# Example plugin entry with parameters:
1895

    
1896
EODA;
1897

    
1898
if($olsrd['enablehttpinfo'] == "on") {
1899
	$olsr .= <<<EODB
1900

    
1901
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1902
{
1903
    PlParam     "port"   "{$olsrd['port']}"
1904
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1905
}
1906

    
1907
EODB;
1908

    
1909
}
1910

    
1911
if($olsrd['enabledsecure'] == "on") {
1912
	$olsr .= <<<EODC
1913

    
1914
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1915
{
1916
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1917
}
1918

    
1919
EODC;
1920

    
1921
}
1922

    
1923
if($olsrd['enabledyngw'] == "on") {
1924

    
1925
	/* unset default route, olsr auto negotiates */
1926
	mwexec("/sbin/route delete default");
1927

    
1928
	$olsr .= <<<EODE
1929

    
1930
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1931
{
1932
    # how often to look for a inet gw, in seconds
1933
    # defaults to 5 secs, if commented out
1934
    PlParam     "Interval"   "{$olsrd['polling']}"
1935

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

    
1946
EODE;
1947

    
1948
}
1949

    
1950
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1951
	$interfaces = explode(',', $conf['iface_array']);
1952
	foreach($interfaces as $interface) {
1953
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1954
$olsr .= <<<EODAD
1955
Interface "{$realinterface}"
1956
{
1957

    
1958
    # Hello interval in seconds(float)
1959
    HelloInterval    2.0
1960

    
1961
    # HELLO validity time
1962
    HelloValidityTime	20.0
1963

    
1964
    # TC interval in seconds(float)
1965
    TcInterval        5.0
1966

    
1967
    # TC validity time
1968
    TcValidityTime	30.0
1969

    
1970
    # MID interval in seconds(float)
1971
    MidInterval	5.0
1972

    
1973
    # MID validity time
1974
    MidValidityTime	30.0
1975

    
1976
    # HNA interval in seconds(float)
1977
    HnaInterval	5.0
1978

    
1979
    # HNA validity time
1980
    HnaValidityTime 	30.0
1981

    
1982
    # When multiple links exist between hosts
1983
    # the weight of interface is used to determine
1984
    # the link to use. Normally the weight is
1985
    # automatically calculated by olsrd based
1986
    # on the characteristics of the interface,
1987
    # but here you can specify a fixed value.
1988
    # Olsrd will choose links with the lowest value.
1989

    
1990
    # Weight 0
1991

    
1992

    
1993
}
1994

    
1995
EODAD;
1996

    
1997
	}
1998
	break;
1999
}
2000
		fwrite($fd, $olsr);
2001
		fclose($fd);
2002
	}
2003

    
2004
	if (is_process_running("olsrd"))
2005
		mwexec("/usr/bin/killall olsrd", true);
2006

    
2007
	sleep(2);
2008

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

    
2011
	conf_mount_ro();
2012
}
2013

    
2014
/* configure cron service */
2015
function configure_cron() {
2016
	global $g, $config;
2017

    
2018
	conf_mount_rw();
2019
	/* preserve existing crontab entries */
2020
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2021

    
2022
	for ($i = 0; $i < count($crontab_contents); $i++) {
2023
		$cron_item =& $crontab_contents[$i];
2024
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
2025
			array_splice($crontab_contents, $i - 1);
2026
			break;
2027
		}
2028
	}
2029
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
2030

    
2031

    
2032
	if (is_array($config['cron']['item'])) {
2033
		$crontab_contents .= "#\n";
2034
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2035
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
2036
		$crontab_contents .= "#\n";
2037

    
2038
		foreach ($config['cron']['item'] as $item) {
2039
			$crontab_contents .= "\n{$item['minute']}\t";
2040
			$crontab_contents .= "{$item['hour']}\t";
2041
			$crontab_contents .= "{$item['mday']}\t";
2042
			$crontab_contents .= "{$item['month']}\t";
2043
			$crontab_contents .= "{$item['wday']}\t";
2044
			$crontab_contents .= "{$item['who']}\t";
2045
			$crontab_contents .= "{$item['command']}";
2046
		}
2047

    
2048
		$crontab_contents .= "\n#\n";
2049
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2050
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2051
		$crontab_contents .= "#\n\n";
2052
	}
2053

    
2054
	/* please maintain the newline at the end of file */
2055
	file_put_contents("/etc/crontab", $crontab_contents);
2056

    
2057
	/* do a HUP kill to force sync changes */
2058
	exec('/bin/pkill -HUP cron');
2059

    
2060
	conf_mount_ro();
2061
}
2062

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

    
2086
function upnp_start() {
2087
	global $config;
2088

    
2089
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2090
		return;
2091

    
2092
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2093
		echo gettext("Starting UPnP service... ");
2094
		require_once('/usr/local/pkg/miniupnpd.inc');
2095
		sync_package_miniupnpd();
2096
		echo "done.\n";
2097
	}
2098
}
2099

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

    
2103
	$is_installed = false;
2104

    
2105
	if(!$config['cron']['item'])
2106
		return;
2107

    
2108
	$x=0;
2109
	foreach($config['cron']['item'] as $item) {
2110
		if(strstr($item['command'], $command)) {
2111
			$is_installed = true;
2112
			break;
2113
		}
2114
		$x++;
2115
	}
2116

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

    
2142
?>
(46-46/64)