Project

General

Profile

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

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

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

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

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

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

    
738
	$dhcpdv6conf = <<<EOD
739

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

    
752
EOD;
753

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

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

    
760
	$dhcpdv6ifs = array();
761

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

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

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

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

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

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

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

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

    
838
		$dnscfgv6 = "";
839

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

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

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

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

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

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

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

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

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

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

    
896
EOD;
897

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

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

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

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

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

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

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

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

    
954
EOD;
955

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

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

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

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

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

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

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

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

    
1003

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

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

    
1014
	return 0;
1015
}
1016

    
1017
function services_igmpproxy_configure() {
1018
        global $config, $g;
1019

    
1020
        /* kill any running igmpproxy */
1021
        killbyname("igmpproxy");
1022

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

    
1026
        $iflist = get_configured_interface_list();
1027

    
1028
        $igmpconf = <<<EOD
1029

    
1030
##------------------------------------------------------
1031
## Enable Quickleave mode (Sends Leave instantly)
1032
##------------------------------------------------------
1033
quickleave
1034

    
1035
EOD;
1036

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

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

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

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

    
1070
        return 0;
1071
}
1072

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

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

    
1085
	$dhcrelaycfg =& $config['dhcrelay'];
1086

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

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

    
1096
	$iflist = get_configured_interface_list();
1097

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

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

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

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

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

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

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

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

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

    
1183
	$cmd .= " " . implode(" ", $srvips);
1184
	mwexec($cmd);
1185

    
1186
	return 0;
1187
}
1188

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

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

    
1201
	$dhcrelaycfg =& $config['dhcrelay6'];
1202

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

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

    
1212
	$iflist = get_configured_interface_list();
1213

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

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

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

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

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

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

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

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

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

    
1299
	$cmd .= " " . implode(" ", $srvips);
1300
	mwexec($cmd);
1301

    
1302
	return 0;
1303
}
1304

    
1305
function services_dyndns_configure_client($conf) {
1306

    
1307
	if (!isset($conf['enable']))
1308
		return;
1309

    
1310
	/* load up the dyndns.class */
1311
	require_once("dyndns.class");
1312

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

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

    
1336
	$dyndnscfg = $config['dyndnses']['dyndns'];
1337

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

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

    
1346
			services_dyndns_configure_client($dyndns);
1347

    
1348
			sleep(1);
1349
		}
1350

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

    
1355
	return 0;
1356
}
1357

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

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

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

    
1371
	if (isset($config['dnsmasq']['enable'])) {
1372

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

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

    
1382
		$args = "";
1383

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

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

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

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

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

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

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

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

    
1424
	return $return;
1425
}
1426

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

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

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

    
1439
	if (isset($config['unbound']['enable'])) {
1440

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

    
1446
		/* generate Unbound config file */
1447
		if(unbound_generate_config()!=0) {
1448
			log_error("Problem generating Unbound configuration.");
1449
			$return = 1;
1450
		}
1451

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

    
1455
		if ($g['booting'])
1456
			echo "done.\n";
1457
	}
1458

    
1459
	return $return;
1460
}
1461

    
1462
function services_snmpd_configure() {
1463
	global $config, $g;
1464
	if(isset($config['system']['developerspew'])) {
1465
		$mt = microtime();
1466
		echo "services_snmpd_configure() being called $mt\n";
1467
	}
1468

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

    
1475
	if (isset($config['snmpd']['enable'])) {
1476

    
1477
		if ($g['booting'])
1478
			echo gettext("Starting SNMP daemon... ");
1479

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

    
1487

    
1488
		$snmpdconf = <<<EOD
1489
location := "{$config['snmpd']['syslocation']}"
1490
contact := "{$config['snmpd']['syscontact']}"
1491
read := "{$config['snmpd']['rocommunity']}"
1492

    
1493
EOD;
1494

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

    
1501
EOD;
1502
		}
1503
*/
1504

    
1505

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

    
1513

    
1514
EOD;
1515
		}
1516

    
1517

    
1518
		$snmpdconf .= <<<EOD
1519
system := 1     # pfSense
1520
%snmpd
1521
begemotSnmpdDebugDumpPdus       = 2
1522
begemotSnmpdDebugSyslogPri      = 7
1523
begemotSnmpdCommunityString.0.1 = $(read)
1524

    
1525
EOD;
1526

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

    
1532
EOD;
1533
		}
1534
*/
1535

    
1536

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

    
1543
EOD;
1544
		}
1545

    
1546

    
1547
		$snmpdconf .= <<<EOD
1548
begemotSnmpdCommunityDisable    = 1
1549

    
1550
EOD;
1551

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

    
1567
		if(is_port( $config['snmpd']['pollport'] )) {
1568
		    $snmpdconf .= <<<EOD
1569
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1570

    
1571
EOD;
1572

    
1573
		}
1574

    
1575
		$snmpdconf .= <<<EOD
1576
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1577
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1578

    
1579
# These are bsnmp macros not php vars.
1580
sysContact      = $(contact)
1581
sysLocation     = $(location)
1582
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1583

    
1584
snmpEnableAuthenTraps = 2
1585

    
1586
EOD;
1587

    
1588
		if (is_array( $config['snmpd']['modules'] )) {
1589
		    if(isset($config['snmpd']['modules']['mibii'])) {
1590
			$snmpdconf .= <<<EOD
1591
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1592

    
1593
EOD;
1594
		    }
1595

    
1596
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1597
			$snmpdconf .= <<<EOD
1598
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1599
%netgraph
1600
begemotNgControlNodeName = "snmpd"
1601

    
1602
EOD;
1603
		    }
1604

    
1605
		    if(isset($config['snmpd']['modules']['pf'])) {
1606
			$snmpdconf .= <<<EOD
1607
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1608

    
1609
EOD;
1610
		    }
1611

    
1612
		    if(isset($config['snmpd']['modules']['hostres'])) {
1613
			$snmpdconf .= <<<EOD
1614
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1615

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

    
1623

    
1624
EOD;
1625
		    }
1626
		}
1627

    
1628
		fwrite($fd, $snmpdconf);
1629
		fclose($fd);
1630

    
1631
		if (isset($config['snmpd']['bindlan'])) {
1632
			$bindlan = "";
1633
		}
1634

    
1635
		/* run bsnmpd */
1636
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1637
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1638

    
1639
		if ($g['booting'])
1640
			echo gettext("done.") . "\n";
1641
	}
1642

    
1643
	return 0;
1644
}
1645

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

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

    
1661
			/* determine interface name */
1662
			$if = get_real_interface($dnsupdate['interface']);
1663
			$wanip = get_interface_ip($dnsupdate['interface']);
1664
			if ($wanip) {
1665

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

    
1671
				$hostname = $dnsupdate['host'];
1672
				/* trailing dot */
1673
				if (substr($hostname, -1) != ".")
1674
					$hostname .= ".";
1675

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

    
1685
EOD;
1686
				fwrite($fd, $privkey);
1687
				fclose($fd);
1688

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

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

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

    
1713
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1714
				fwrite($fd, $upinst);
1715
				fclose($fd);
1716

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

    
1723
				mwexec_bg($cmd);
1724
			}
1725
		}
1726
	}
1727

    
1728
	return 0;
1729
}
1730

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

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

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

    
1770
# This file is an example of a typical
1771
# configuration for a mostly static
1772
# network(regarding mobility) using
1773
# the LQ extention
1774

    
1775
# Debug level(0-9)
1776
# If set to 0 the daemon runs in the background
1777

    
1778
DebugLevel	2
1779

    
1780
# IP version to use (4 or 6)
1781

    
1782
IpVersion	4
1783

    
1784
# Clear the screen each time the internal state changes
1785

    
1786
ClearScreen     yes
1787

    
1788
{$enableannounce}
1789

    
1790
# Should olsrd keep on running even if there are
1791
# no interfaces available? This is a good idea
1792
# for a PCMCIA/USB hotswap environment.
1793
# "yes" OR "no"
1794

    
1795
AllowNoInt	yes
1796

    
1797
# TOS(type of service) value for
1798
# the IP header of control traffic.
1799
# If not set it will default to 16
1800

    
1801
#TosValue	16
1802

    
1803
# The fixed willingness to use(0-7)
1804
# If not set willingness will be calculated
1805
# dynamically based on battery/power status
1806
# if such information is available
1807

    
1808
#Willingness    	4
1809

    
1810
# Allow processes like the GUI front-end
1811
# to connect to the daemon.
1812

    
1813
IpcConnect
1814
{
1815
     # Determines how many simultaneously
1816
     # IPC connections that will be allowed
1817
     # Setting this to 0 disables IPC
1818

    
1819
     MaxConnections  0
1820

    
1821
     # By default only 127.0.0.1 is allowed
1822
     # to connect. Here allowed hosts can
1823
     # be added
1824

    
1825
     Host            127.0.0.1
1826
     #Host            10.0.0.5
1827

    
1828
     # You can also specify entire net-ranges
1829
     # that are allowed to connect. Multiple
1830
     # entries are allowed
1831

    
1832
     #Net             192.168.1.0 255.255.255.0
1833
}
1834

    
1835
# Wether to use hysteresis or not
1836
# Hysteresis adds more robustness to the
1837
# link sensing but delays neighbor registration.
1838
# Used by default. 'yes' or 'no'
1839

    
1840
UseHysteresis	no
1841

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

    
1851
#HystScaling	0.50
1852
#HystThrHigh	0.80
1853
#HystThrLow	0.30
1854

    
1855

    
1856
# Link quality level
1857
# 0 = do not use link quality
1858
# 1 = use link quality for MPR selection
1859
# 2 = use link quality for MPR selection and routing
1860
# Defaults to 0
1861

    
1862
LinkQualityLevel	{$olsrd['enablelqe']}
1863

    
1864
# Link quality window size
1865
# Defaults to 10
1866

    
1867
LinkQualityWinSize	10
1868

    
1869
# Polling rate in seconds(float).
1870
# Default value 0.05 sec
1871

    
1872
Pollrate	0.05
1873

    
1874

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

    
1885
TcRedundancy	2
1886

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

    
1896
MprCoverage	3
1897

    
1898
# Example plugin entry with parameters:
1899

    
1900
EODA;
1901

    
1902
if($olsrd['enablehttpinfo'] == "on") {
1903
	$olsr .= <<<EODB
1904

    
1905
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1906
{
1907
    PlParam     "port"   "{$olsrd['port']}"
1908
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1909
}
1910

    
1911
EODB;
1912

    
1913
}
1914

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

    
1918
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1919
{
1920
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1921
}
1922

    
1923
EODC;
1924

    
1925
}
1926

    
1927
if($olsrd['enabledyngw'] == "on") {
1928

    
1929
	/* unset default route, olsr auto negotiates */
1930
	mwexec("/sbin/route delete default");
1931

    
1932
	$olsr .= <<<EODE
1933

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

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

    
1950
EODE;
1951

    
1952
}
1953

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

    
1962
    # Hello interval in seconds(float)
1963
    HelloInterval    2.0
1964

    
1965
    # HELLO validity time
1966
    HelloValidityTime	20.0
1967

    
1968
    # TC interval in seconds(float)
1969
    TcInterval        5.0
1970

    
1971
    # TC validity time
1972
    TcValidityTime	30.0
1973

    
1974
    # MID interval in seconds(float)
1975
    MidInterval	5.0
1976

    
1977
    # MID validity time
1978
    MidValidityTime	30.0
1979

    
1980
    # HNA interval in seconds(float)
1981
    HnaInterval	5.0
1982

    
1983
    # HNA validity time
1984
    HnaValidityTime 	30.0
1985

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

    
1994
    # Weight 0
1995

    
1996

    
1997
}
1998

    
1999
EODAD;
2000

    
2001
	}
2002
	break;
2003
}
2004
		fwrite($fd, $olsr);
2005
		fclose($fd);
2006
	}
2007

    
2008
	if (is_process_running("olsrd"))
2009
		mwexec("/usr/bin/killall olsrd", true);
2010

    
2011
	sleep(2);
2012

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

    
2015
	conf_mount_ro();
2016
}
2017

    
2018
/* configure cron service */
2019
function configure_cron() {
2020
	global $g, $config;
2021

    
2022
	conf_mount_rw();
2023
	/* preserve existing crontab entries */
2024
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2025

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

    
2035

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

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

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

    
2058
	/* please maintain the newline at the end of file */
2059
	file_put_contents("/etc/crontab", $crontab_contents);
2060

    
2061
	/* do a HUP kill to force sync changes */
2062
	exec('/bin/pkill -HUP cron');
2063

    
2064
	conf_mount_ro();
2065
}
2066

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

    
2090
function upnp_start() {
2091
	global $config;
2092

    
2093
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2094
		return;
2095

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

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

    
2107
	$is_installed = false;
2108

    
2109
	if(!$config['cron']['item'])
2110
		return;
2111

    
2112
	$x=0;
2113
	foreach($config['cron']['item'] as $item) {
2114
		if(strstr($item['command'], $command)) {
2115
			$is_installed = true;
2116
			break;
2117
		}
2118
		$x++;
2119
	}
2120

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

    
2146
?>
(47-47/65)