Project

General

Profile

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

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

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

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

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

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

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

    
43
/* implement ipv6 route advertising deamon */
44
function services_radvd_configure() {
45
	global $config, $g;
46
	
47
	if ($g['platform'] == 'jail') 
48
		return;
49

    
50
	if(isset($config['system']['developerspew'])) {
51
		$mt = microtime();
52
		echo "services_radvd_configure() being called $mt\n";
53
	}
54

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

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

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

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

    
75
	$radvdconf = "# Automatically Generated, do not edit\n";
76

    
77
	/* Process all links which need the router advertise daemon */
78
	$radvdnum = 0;
79
	$radvdifs = array();
80

    
81
	/* handle manually configured DHCP6 server settings first */
82
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
83
		if(!isset($config['interfaces'][$dhcpv6if]['enable']))
84
			continue;
85
								
86
		/* are router advertisements enabled? */
87
		if($dhcpv6ifconf['ramode'] == "disabled")
88
			continue;
89

    
90
		/* check if we need to listen on a CARP interface */
91
		$carplist = get_configured_carp_interface_list();
92
		if($dhcpv6ifconf['rainterface'] <> "") {
93
			if($carplist[$dhcpv6ifconf['rainterface']] <> "") {
94
				$realif = $dhcpv6ifconf['rainterface'];
95
			} else {
96
				$realif = get_real_interface($dhcpv6if);
97
			}
98
		}
99
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
100
		if(!is_ipaddrv6($ifcfgipv6))
101
			continue;
102

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

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

    
160
		/* add DNS servers */
161
		$dnslist = array();
162
		if(!empty($dhcpv6ifconf['dnsserver'][0])) {
163
			foreach($dhcpv6ifconf['dnsserver'] as $server) {
164
				if(is_ipaddrv6($server))
165
					$dnslist[] = $server;
166
			}
167
		} elseif (isset($config['dnsmasq']['enable'])) {
168
			$dnslist[] = get_interface_ipv6($dhcpv6if);
169
		} elseif (!empty($config['system']['dnsserver'][0])) {
170
			foreach($config['system']['dnsserver'] as $server) {
171
				if(is_ipaddrv6($server))
172
					$dnslist[] = $server;
173
			}
174
		}
175
		if(count($dnslist) > 0) {
176
			$dnsstring = implode(" ", $dnslist);
177
			if($dnsstring <> "")
178
				$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
179
		}
180
		if($dhcpv6ifconf['domain'] <> "") {
181
			$radvdconf .= "\tDNSSL {$dhcpv6ifconf['domain']} { };\n";
182
		} elseif ($config['system']['domain'] <> "") {
183
			$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
184
		}
185
		$radvdconf .= "};\n";
186
		$radvdnum++;
187
	}
188

    
189
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
190
	foreach ($Iflist as $if => $ifdescr) {
191
		if(!isset($config['interfaces'][$if]['track6-interface']))
192
			continue;
193
		if(!isset($config['interfaces'][$if]['enable']))
194
			continue;
195
			
196
		$realif = get_real_interface($if);
197
		/* prevent duplicate entries, manual overrides */
198
		if(in_array($realif, $radvdifs))
199
			continue;
200

    
201
		$ifcfgipv6 = get_interface_ipv6($if);
202
		if(!is_ipaddrv6($ifcfgipv6))
203
			continue;
204

    
205
		$ifcfgsnv6 = get_interface_subnetv6($if);
206
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
207
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
208
		$trackif = $config['interfaces'][$if]['track6-interface'];
209
		$radvdifs[] = $realif;
210

    
211
		$autotype = $config['interfaces'][$trackif]['ipaddrv6'];
212
	
213
		log_error("configuring RA on {$if} for type {$autotype} radvd subnet {$subnetv6}/{$ifcfgsnv6}");
214

    
215
		$dnslist = array();
216
		if(is_ipaddrv6($subnetv6)) {
217
			$radvdconf .= "# Generated config for {$autotype} delegation from {$trackif} on {$if}\n";
218
			$radvdconf .= "interface {$realif} {\n";
219
				$radvdconf .= "\tAdvSendAdvert on;\n";
220
				$radvdconf .= "\tMinRtrAdvInterval 3;\n";
221
				$radvdconf .= "\tMaxRtrAdvInterval 10;\n";
222
				$radvdconf .= "\tAdvLinkMTU 1280;\n";
223
				$radvdconf .= "\tAdvOtherConfigFlag on;\n";
224
					$radvdconf .= "\t\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
225
					$radvdconf .= "\t\tAdvOnLink on;\n";
226
					$radvdconf .= "\t\tAdvAutonomous on;\n";
227
					$radvdconf .= "\t\tAdvRouterAddr on;\n";
228
				$radvdconf .= "\t};\n";
229

    
230
				/* add DNS servers */
231
				$dnslist = array();
232
				if (isset($config['dnsmasq']['enable'])) {
233
						$dnslist[] = $ifcfgipv6;
234
				} elseif (!empty($config['system']['dnsserver'][0])) {
235
					foreach($config['system']['dnsserver'] as $server) {
236
						if(is_ipaddrv6($server))
237
							$dnslist[] = $server;
238
					}
239
				}
240
				if(count($dnslist) > 0) {
241
					$dnsstring = implode(" ", $dnslist);
242
					if($dnsstring <> "")
243
						$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
244
				}
245
				if ($config['system']['domain'] <> "") {
246
					$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
247
				}
248
			$radvdconf .= "};\n";
249
			$radvdnum++;
250
		}
251
	}
252

    
253
	fwrite($fd, $radvdconf);
254
	fclose($fd);
255

    
256
	if(count($radvdifs) > 0) {
257
		mwexec("/usr/local/sbin/radvd -C {$g['varetc_path']}/radvd.conf -m syslog");
258
	}
259
	return 0;
260
}
261

    
262
function services_dhcpd_configure() {
263
	global $config, $g;
264

    
265
	/* configure DHCPD chroot once */
266
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
267
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
268
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
269
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
270
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
271
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
272
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
273
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
274
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
275
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
276
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
277
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
278
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
279
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
280
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
281

    
282
	if(!trim($status))
283
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
284
	fclose($fd);
285
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
286

    
287
	services_dhcpdv4_configure();
288
	services_dhcpdv6_configure();
289
	services_radvd_configure();
290
	return;
291

    
292
}
293
function services_dhcpdv4_configure() {
294
	global $config, $g;
295

    
296
	if($g['services_dhcp_server_enable'] == false)
297
		return;
298

    
299
	if(isset($config['system']['developerspew'])) {
300
		$mt = microtime();
301
		echo "services_dhcpdv4_configure($if) being called $mt\n";
302
	}
303

    
304
	/* kill any running dhcpd */
305
	if(is_process_running("dhcpd")) {
306
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
307
	}
308

    
309
	/* DHCP enabled on any interfaces? */
310
	if (!is_dhcp_server_enabled())
311
		return 0;
312

    
313
	/* if OLSRD is enabled, allow WAN to house DHCP. */
314
	if($config['installedpackages']['olsrd'])
315
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
316
				if($olsrd['enable'])
317
					$is_olsr_enabled = true;
318

    
319
	if ($g['booting']) {
320
		if ($g['platform'] != "pfSense") {
321
			/* restore the leases, if we have them */
322
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
323
				$dhcprestore = "";
324
				$dhcpreturn = "";
325
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
326
				$dhcprestore = implode(" ", $dhcprestore);
327
				if($dhcpreturn <> 0) {
328
					log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n"));
329
				}
330
			}
331
		}
332
	}
333

    
334
	$syscfg = $config['system'];
335
	if (!is_array($config['dhcpd']))
336
		$config['dhcpd'] = array();
337
	$dhcpdcfg = $config['dhcpd'];
338
	$Iflist = get_configured_interface_list();
339

    
340
	if ($g['booting'])
341
		echo gettext("Starting DHCP service...");
342
	else
343
		sleep(1);
344

    
345
	/* write dhcpd.conf */
346
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
347
	if (!$fd) {
348
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
349
		return 1;
350
	}
351

    
352
	$custoptions = "";
353
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
354
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
355
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
356
				if(!empty($item['type']))
357
					$itemtype = $item['type'];
358
				else
359
					$itemtype = "text";
360
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
361
			}
362
		}
363
	}
364

    
365
	$dhcpdconf = <<<EOD
366

    
367
option domain-name "{$syscfg['domain']}";
368
option ldap-server code 95 = text;
369
option domain-search-list code 119 = text;
370
{$custoptions}
371
default-lease-time 7200;
372
max-lease-time 86400;
373
log-facility local7;
374
ddns-update-style none;
375
one-lease-per-client true;
376
deny duplicates;
377
ping-check true;
378

    
379
EOD;
380

    
381
	if(!isset($dhcpifconf['disableauthoritative']))
382
		$dhcpdconf .= "authoritative;\n";
383

    
384
	if(isset($dhcpifconf['alwaysbroadcast']))
385
		$dhcpdconf .= "always-broadcast on\n";
386

    
387
	$dhcpdifs = array();
388
	$add_routers = false;
389
	$gateways_arr = return_gateways_array();
390
	/* only add a routers line if the system has any IPv4 gateway at all */
391
	/* a static route has a gateway, manually overriding this field always works */
392
	foreach($gateways_arr as $gwitem) {
393
		if($gwitem['ipprotocol'] == "inet") {
394
			$add_routers = true;
395
			break;
396
		}
397
	}
398

    
399
	/*    loop through and determine if we need to setup
400
	 *    failover peer "bleh" entries
401
	 */
402
	$dhcpnum = 0;
403
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
404

    
405
		interfaces_staticarp_configure($dhcpif);
406

    
407
		if (!isset($dhcpifconf['enable']))
408
			continue;
409

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

    
456
EOPP;
457
		$dhcpnum++;
458
		}
459
	}
460

    
461
	$dhcpnum = 0;
462

    
463
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
464

    
465
		$ifcfg = $config['interfaces'][$dhcpif];
466

    
467
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
468
			continue;
469
		$ifcfgip = get_interface_ip($dhcpif);
470
		$ifcfgsn = get_interface_subnet($dhcpif);
471
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
472
		$subnetmask = gen_subnet_mask($ifcfgsn);
473

    
474
		if (!is_ipaddr($subnet))
475
			continue;
476

    
477
		if($is_olsr_enabled == true)
478
			if($dhcpifconf['netmask'])
479
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
480

    
481
		$dnscfg = "";
482

    
483
		if ($dhcpifconf['domain']) {
484
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
485
		}
486

    
487
		if($dhcpifconf['domainsearchlist'] <> "") {
488
			$dnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpifconf['domainsearchlist'])) . "\";\n";
489
		}
490

    
491
		if (isset($dhcpifconf['ddnsupdate'])) {
492
			if($dhcpifconf['ddnsdomain'] <> "") {
493
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
494
			}
495
			$dnscfg .= "	ddns-update-style interim;\n";
496
		}
497

    
498
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
499
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
500
		} else if (isset($config['dnsmasq']['enable'])) {
501
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
502
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
503
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
504
		}
505

    
506
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
507
		$dhcpdconf .= "	pool {\n";
508

    
509
		/* is failover dns setup? */
510
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
511
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
512
			if($dhcpifconf['dnsserver'][1] <> "")
513
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
514
			$dhcpdconf .= ";\n";
515
		}
516

    
517
		if($dhcpifconf['failover_peerip'] <> "")
518
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
519

    
520
		if (isset($dhcpifconf['denyunknown']))
521
		   $dhcpdconf .= "		deny unknown-clients;\n";
522

    
523
		if ($dhcpifconf['gateway']) {
524
			$routers = $dhcpifconf['gateway'];
525
			$add_routers = true;
526
		} else {
527
			$routers = $ifcfgip;
528
		}
529

    
530
		if($dhcpifconf['failover_peerip'] <> "") {
531
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
532
			$dhcpnum++;
533
		}
534

    
535
		$dhcpdconf .= <<<EOD
536
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
537
	}
538

    
539
EOD;
540

    
541
		if($add_routers)
542
			$dhcpdconf .= "	option routers {$routers};\n";
543
		$dhcpdconf .= <<<EOD
544
$dnscfg
545

    
546
EOD;
547
    		// default-lease-time
548
		if ($dhcpifconf['defaultleasetime'])
549
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
550

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

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

    
561
		// ntp-servers
562
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
563
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
564

    
565
		// tftp-server-name
566
		if ($dhcpifconf['tftp'] <> "")
567
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
568

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

    
580
		// ldap-server
581
		if ($dhcpifconf['ldap'] <> "")
582
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
583

    
584
		// net boot information
585
		if(isset($dhcpifconf['netboot'])) {
586
			if ($dhcpifconf['nextserver'] <> "") {
587
				$dhcpdconf .= "	next-server {$dhcpifconf['nextserver']};\n";
588
			}
589
			if ($dhcpifconf['filename'] <> "") {
590
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
591
			}
592
			if ($dhcpifconf['rootpath'] <> "") {
593
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
594
      		}
595
		}
596

    
597
		$dhcpdconf .= <<<EOD
598
}
599

    
600
EOD;
601

    
602
		/* add static mappings */
603
		if (is_array($dhcpifconf['staticmap'])) {
604

    
605
			$i = 0;
606
			foreach ($dhcpifconf['staticmap'] as $sm) {
607
				$dhcpdconf .= <<<EOD
608
host s_{$dhcpif}_{$i} {
609
	hardware ethernet {$sm['mac']};
610

    
611
EOD;
612
				if ($sm['ipaddr'])
613
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
614

    
615
				if ($sm['hostname']) {
616
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
617
					$dhhostname = str_replace(".", "_", $dhhostname);
618
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
619
				}
620
				if ($sm['filename'])
621
					$dhcpdconf .= "	filename \"{$sm['filename']}\";\n";
622

    
623
				if ($sm['rootpath'])
624
					$dhcpdconf .= "	option root-path \"{$sm['rootpath']}\";\n";
625

    
626
				$dhcpdconf .= "}\n";
627
				$i++;
628
			}
629
		}
630

    
631
		$dhcpdifs[] = get_real_interface($dhcpif);
632
	}
633

    
634
	fwrite($fd, $dhcpdconf);
635
	fclose($fd);
636

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

    
640

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

    
647
	if ($g['booting']) {
648
		print "done.\n";
649
	}
650

    
651
	return 0;
652
}
653

    
654
function services_dhcpdv6_configure() {
655
	global $config, $g;
656

    
657
	if($g['services_dhcp_server_enable'] == false)
658
		return;
659

    
660
	if(isset($config['system']['developerspew'])) {
661
		$mt = microtime();
662
		echo "services_dhcpd_configure($if) being called $mt\n";
663
	}
664

    
665
	/* kill any running dhcpd */
666
	if(is_process_running("dhcpd")) {
667
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
668
		killbypid("{$g['varrun_path']}/dhcpleases6.pid");
669
	}
670

    
671
	/* DHCP enabled on any interfaces? */
672
	if (!is_dhcpv6_server_enabled())
673
		return 0;
674

    
675
	if ($g['booting']) {
676
		if ($g['platform'] != "pfSense") {
677
			/* restore the leases, if we have them */
678
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
679
				$dhcprestore = "";
680
				$dhcpreturn = "";
681
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
682
				$dhcprestore = implode(" ", $dhcprestore);
683
				if($dhcpreturn <> 0) {
684
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
685
				}
686
			}
687
		}
688
	}
689

    
690
	$syscfg = $config['system'];
691
	if (!is_array($config['dhcpdv6']))
692
		$config['dhcpdv6'] = array();
693
	$dhcpdv6cfg = $config['dhcpdv6'];
694
	$Iflist = get_configured_interface_list();
695

    
696
	if ($g['booting'])
697
		echo "Starting DHCPv6 service...";
698
	else
699
		sleep(1);
700

    
701
	/* we add a fake entry for interfaces that are set to track6 another WAN */
702
	foreach($Iflist as $ifname) {
703
		$realif = get_real_interface($ifname);
704
		$ifcfgipv6 = find_interface_ipv6($realif);
705
		if(!is_ipaddrv6($ifcfgipv6))
706
			continue;
707
		$ifcfgipv6 = Net_IPv6::getNetmask($ifcfgipv6, 64);
708
		if($config['interfaces'][$ifname]['track6-interface'] <> "") {
709
			$trackifname = $config['interfaces'][$ifname]['track6-interface'];
710
			$trackcfg = $config['interfaces'][$trackifname];
711
			$pdlen = calculate_ipv6_delegation_length($trackifname);
712
			$ifcfgipv6arr =explode(":", $ifcfgipv6);
713
			$dhcpdv6cfg[$ifname] = array();
714
			$dhcpdv6cfg[$ifname]['enable'] = true;
715
			/* range */
716
			$ifcfgipv6arr[7] = "1000";
717
			$dhcpdv6cfg[$ifname]['range']['from'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));
718
			$ifcfgipv6arr[7] = "2000";
719
			$dhcpdv6cfg[$ifname]['range']['to'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));;
720
			/* prefix length > 0? We can add dhcp6 prefix delegation server */
721
			if($pdlen > 2) {
722
				$pdlenmax = $pdlen;
723
				$pdlenhalf = $pdlenmax -1;
724
				$pdlenmin = (64 - ceil($pdlenhalf / 4));
725
				$dhcpdv6cfg[$ifname]['prefixrange']['prefixlength'] = $pdlenmin;
726

    
727
				/* set the delegation start to half the current address block */
728
				$range = Net_IPv6::parseAddress($ifcfgipv6, (64 - $pdlenmax));
729
				$range['start'] = Net_IPv6::getNetmask($range['end'], (64 - $pdlenhalf));
730

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

    
735
				$dhcpdv6cfg[$ifname]['prefixrange']['from'] = Net_IPv6::compress($range['start']);
736
				$dhcpdv6cfg[$ifname]['prefixrange']['to'] = Net_IPv6::compress($range['end']);
737
			}
738
		}
739
	}
740

    
741
	/* write dhcpdv6.conf */
742
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
743
	if (! $fdv6) {
744
		printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n");
745
		return 1;
746
	}
747

    
748
	$custoptionsv6 = "";
749
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
750
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
751
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
752
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
753
			}
754
		}
755
	}
756

    
757
	$dhcpdv6conf = <<<EOD
758

    
759
option domain-name "{$syscfg['domain']}";
760
option ldap-server code 95 = text;
761
option domain-search-list code 119 = text;
762
{$custoptions}
763
default-lease-time 7200;
764
max-lease-time 86400;
765
log-facility local7;
766
ddns-update-style none;
767
one-lease-per-client true;
768
deny duplicates;
769
ping-check true;
770

    
771
EOD;
772

    
773
	if(!isset($dhcpv6ifconf['disableauthoritative']))
774
		$dhcpdv6conf .= "authoritative;\n";
775

    
776
	if(isset($dhcpv6ifconf['alwaysbroadcast']))
777
		$dhcpdv6conf .= "always-broadcast on\n";
778

    
779
	$dhcpdv6ifs = array();
780

    
781
	/*    loop through and determine if we need to setup
782
	 *    failover peer "bleh" entries
783
	 */
784
	$dhcpv6num = 0;
785
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
786

    
787
		if (!isset($dhcpv6ifconf['enable']))
788
			continue;
789

    
790
		if($dhcpv6ifconf['failover_peerip'] <> "") {
791
			$intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']);
792
			$intipv6 = find_interface_ipv6($intv6);
793
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
794
			/*
795
			 *    yep, failover peer is defined.
796
			 *    does it match up to a defined vip?
797
			 */
798
			$skew = 110;
799
			$a_vip = &$config['virtualip']['vip'];
800
			if(is_array($a_vip)) {
801
				foreach ($a_vip as $vipent) {
802
					if($intv6 == $real_dhcpv6if) {
803
						/* this is the interface! */
804
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
805
							$skew = 0;
806
					}
807
				}
808
			} else {
809
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
810
			}
811
			if($skew > 10) {
812
				$typev6 = "secondary";
813
				$dhcpdv6conf_pri  = "mclt 600;\n";
814
				$my_portv6 = "520";
815
				$peer_portv6 = "519";
816
			} else {
817
				$my_portv6 = "519";
818
				$peer_portv6 = "520";
819
				$typev6 = "primary";
820
				$dhcpdv6conf_pri  = "split 128;\n";
821
				$dhcpdv6conf_pri .= "  mclt 600;\n";
822
			}
823
			$dhcpdv6conf .= <<<EOPP
824
failover peer "dhcpv6{$dhcpv6num}" {
825
  {$typev6};
826
  address {$intipv6};
827
  port {$my_portv6};
828
  peer address {$dhcpv6ifconf['failover_peerip']};
829
  peer port {$peer_portv6};
830
  max-response-delay 10;
831
  max-unacked-updates 10;
832
  {$dhcpdv6conf_pri}
833
  load balance max seconds 3;
834
}
835

    
836
EOPP;
837
		$dhcpv6num++;
838
		}
839
	}
840

    
841
	$dhcpv6num = 0;
842
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
843

    
844
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
845

    
846
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
847
			continue;
848
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
849
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
850
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
851
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
852

    
853
		if($is_olsr_enabled == true)
854
			if($dhcpv6ifconf['netmask'])
855
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
856

    
857
		$dnscfgv6 = "";
858

    
859
		if ($dhcpv6ifconf['domain']) {
860
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
861
		}
862

    
863
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
864
			$dnscfgv6 .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpv6ifconf['domainsearchlist'])) . "\";\n";
865
    		}
866

    
867
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
868
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
869
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
870
			}
871
			$dnscfgv6 .= "	ddns-update-style interim;\n";
872
		}
873

    
874
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
875
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
876
		} else if (isset($config['dnsmasq']['enable'])) {
877
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
878
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
879
			$dns_arrv6 = array();
880
			foreach($syscfg['dnsserver'] as $dnsserver) {
881
				if(is_ipaddrv6($dnsserver)) {
882
					$dns_arrv6[] = $dnsserver;
883
				}
884
			}
885
			if(!empty($dns_arrv6))
886
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
887
		}
888

    
889
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
890
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
891

    
892
		if($dhcpv6ifconf['failover_peerip'] <> "")
893
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
894

    
895
		if (isset($dhcpv6ifconf['denyunknown']))
896
		   $dhcpdv6conf .= "		deny unknown-clients;\n";
897

    
898
		if($dhcpv6ifconf['failover_peerip'] <> "") {
899
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
900
			$dhcpv6num++;
901
		}
902

    
903
		$dhcpdv6conf .= <<<EOD
904
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
905
$dnscfgv6
906

    
907
EOD;
908

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

    
912
		}
913
    		// default-lease-time
914
		if ($dhcpv6ifconf['defaultleasetime'])
915
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
916

    
917
		// max-lease-time
918
		if ($dhcpv6ifconf['maxleasetime'])
919
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
920

    
921
		// ntp-servers
922
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) {
923
			$ntpservers = array();
924
			foreach($dhcpv6ifconf['ntpserver'] as $ntpserver) {
925
				if(is_ipaddrv6($ntpserver))
926
					$ntpservers[] = $ntpserver;
927
			}
928
			if(count($ntpservers) > 0 )
929
				$dhcpdv6conf .= "       option dhcp6.sntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
930
		}
931
		// tftp-server-name
932
		/* Needs ISC DHCPD support
933
		 if ($dhcpv6ifconf['tftp'] <> "")
934
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
935
		*/
936

    
937
		// Handle option, number rowhelper values
938
		$dhcpdv6conf .= "\n";
939
		if($dhcpv6ifconf['numberoptions']['item']) {
940
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
941
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
942
			}
943
		}
944

    
945
		// ldap-server
946
		if ($dhcpv6ifconf['ldap'] <> "")
947
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
948

    
949
		// net boot information
950
		if(isset($dhcpv6ifconf['netboot'])) {
951
			if ($dhcpv6ifconf['nextserver'] <> "") {
952
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['nextserver']};\n";
953
			}
954
			if ($dhcpv6ifconf['filename'] <> "") {
955
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
956
			}
957
			if ($dhcpv6ifconf['rootpath'] <> "") {
958
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
959
      		}
960
	}
961

    
962
		$dhcpdv6conf .= <<<EOD
963
}
964

    
965
EOD;
966

    
967
		/* add static mappings */
968
		/* Needs to use DUID */
969
		if (is_array($dhcpv6ifconf['staticmap'])) {
970

    
971
			$i = 0;
972
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
973
				$dhcpdv6conf .= <<<EOD
974
host s_{$dhcpv6if}_{$i} {
975
	host-identifier option dhcp6.client-id {$sm['duid']};
976

    
977
EOD;
978
				if ($sm['ipaddrv6'])
979
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
980

    
981
				if ($sm['hostname']) {
982
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
983
					$dhhostname = str_replace(".", "_", $dhhostname);
984
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
985
				}
986
				if ($sm['filename'])
987
					$dhcpdv6conf .= "	filename \"{$sm['filename']}\";\n";
988

    
989
				if ($sm['rootpath'])
990
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
991

    
992
				$dhcpdv6conf .= "}\n";
993
				$i++;
994
			}
995
		}
996

    
997
		if($config['dhcpdv6'][$dhcpv6if]['ramode'] <> "unmanaged") {
998
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
999
			$dhcpdv6ifs[] = $realif;
1000
			exec("/sbin/ifconfig {$realif} |awk  '/ether/ {print $2}'", $mac);
1001
			$v6address = generate_ipv6_from_mac($mac[0]);
1002
			/* Create link local address for bridges */
1003
			if(stristr("$realif", "bridge")) {
1004
				mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
1005
			}
1006
		}
1007
	}
1008

    
1009
	fwrite($fdv6, $dhcpdv6conf);
1010
	fclose($fdv6);
1011
	/* create an empty leases v6 database */
1012
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1013

    
1014

    
1015
	/* fire up dhcpd in a chroot */
1016
	if(count($dhcpdv6ifs) > 0) {
1017
		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 " .
1018
			join(" ", $dhcpdv6ifs));
1019
		mwexec("/usr/local/sbin/dhcpleases6 -c \"/usr/local/bin/php -f /usr/local/sbin/prefixes.php|/bin/sh\" -l {$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1020
	}
1021

    
1022
	if ($g['booting']) {
1023
		print gettext("done.") . "\n";
1024
	}
1025

    
1026
	return 0;
1027
}
1028

    
1029
function services_igmpproxy_configure() {
1030
        global $config, $g;
1031

    
1032
        /* kill any running igmpproxy */
1033
        killbyname("igmpproxy");
1034

    
1035
	if (!is_array($config['igmpproxy']['igmpentry']))
1036
		return 1;
1037

    
1038
        $iflist = get_configured_interface_list();
1039

    
1040
        $igmpconf = <<<EOD
1041

    
1042
##------------------------------------------------------
1043
## Enable Quickleave mode (Sends Leave instantly)
1044
##------------------------------------------------------
1045
quickleave
1046

    
1047
EOD;
1048

    
1049
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
1050
                unset($iflist[$igmpcf['ifname']]);
1051
                $realif = get_real_interface($igmpcf['ifname']);
1052
                if (empty($igmpcf['threshold']))
1053
                        $threshld = 1;
1054
                else
1055
                        $threshld = $igmpcf['threshold'];
1056
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
1057

    
1058
                if ($igmpcf['address'] <> "") {
1059
                        $item = explode(" ", $igmpcf['address']);
1060
                        foreach($item as $iww)
1061
                                $igmpconf .= "altnet {$iww}\n";
1062
                }
1063
                $igmpconf .= "\n";
1064
        }
1065
        foreach ($iflist as $ifn) {
1066
                $realif = get_real_interface($ifn);
1067
                $igmpconf .= "phyint {$realif} disabled\n";
1068
        }
1069
	$igmpconf .= "\n";
1070

    
1071
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
1072
        if (!$igmpfl) {
1073
                log_error(gettext("Could not write Igmpproxy configuration file!"));
1074
                return;
1075
        }
1076
        fwrite($igmpfl, $igmpconf);
1077
        fclose($igmpfl);
1078

    
1079
        mwexec("/usr/local/sbin/igmpproxy -c " . $g['tmp_path'] . "/igmpproxy.conf");
1080
        log_error(gettext("Started IGMP proxy service."));
1081

    
1082
        return 0;
1083
}
1084

    
1085
function services_dhcrelay_configure() {
1086
	global $config, $g;
1087
	if ($g['platform'] == 'jail')
1088
		return;
1089
	if(isset($config['system']['developerspew'])) {
1090
		$mt = microtime();
1091
		echo "services_dhcrelay_configure() being called $mt\n";
1092
	}
1093

    
1094
	/* kill any running dhcrelay */
1095
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1096

    
1097
	$dhcrelaycfg =& $config['dhcrelay'];
1098

    
1099
	/* DHCPRelay enabled on any interfaces? */
1100
	if (!isset($dhcrelaycfg['enable']))
1101
		return 0;
1102

    
1103
	if ($g['booting'])
1104
		echo gettext("Starting DHCP relay service...");
1105
	else
1106
		sleep(1);
1107

    
1108
	$iflist = get_configured_interface_list();
1109

    
1110
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1111
	foreach ($dhcifaces as $dhcrelayif) {
1112
		if (!isset($iflist[$dhcrelayif]) ||
1113
			link_interface_to_bridge($dhcrelayif))
1114
			continue;
1115

    
1116
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
1117
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1118
	}
1119

    
1120
	/*
1121
	 * In order for the relay to work, it needs to be active
1122
	 * on the interface in which the destination server sits.
1123
	 */
1124
	$srvips = explode(",", $dhcrelaycfg['server']);
1125
	foreach ($srvips as $srcidx => $srvip) {
1126
		unset($destif);
1127
		foreach ($iflist as $ifname) {
1128
			$subnet = get_interface_ip($ifname);
1129
			if (!is_ipaddr($subnet))
1130
				continue;
1131
			$subnet .=  "/" . get_interface_subnet($ifname);
1132
			if (ip_in_subnet($srvip, $subnet)) {
1133
				$destif = get_real_interface($ifname);
1134
				break;
1135
			}
1136
		}
1137
		if (!isset($destif)) {
1138
			foreach (get_staticroutes() as $rtent) {
1139
				if (ip_in_subnet($srvip, $rtent['network'])) {
1140
					$a_gateways = return_gateways_array(true);
1141
					$destif = $a_gateways[$rtent['gateway']]['interface'];
1142
					break;
1143
				}
1144
			}
1145
		}
1146

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

    
1164
		if (!isset($destif)) {
1165
			if (is_array($config['gateways']['gateway_item'])) {
1166
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1167
					if (isset($gateway['defaultgw'])) {
1168
						$a_gateways = return_gateways_array(true);
1169
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1170
						break;
1171
					}
1172
				}
1173
			} else
1174
				$destif = get_real_interface("wan");
1175
		}
1176

    
1177
		if (!empty($destif))
1178
			$dhcrelayifs[] = $destif;
1179
	}
1180
	$dhcrelayifs = array_unique($dhcrelayifs);
1181

    
1182
	/* fire up dhcrelay */
1183
	if (empty($dhcrelayifs)) {
1184
		log_error("No suitable interface found for running dhcrelay!");
1185
		return; /* XXX */
1186
	}
1187

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

    
1190
	if (isset($dhcrelaycfg['agentoption']))
1191
		$cmd .=  " -a -m replace";
1192

    
1193
	$cmd .= " " . implode(" ", $srvips);
1194
	mwexec($cmd);
1195

    
1196
	return 0;
1197
}
1198

    
1199
function services_dhcrelay6_configure() {
1200
	global $config, $g;
1201
	if ($g['platform'] == 'jail')
1202
		return;
1203
	if(isset($config['system']['developerspew'])) {
1204
		$mt = microtime();
1205
		echo "services_dhcrelay_configure() being called $mt\n";
1206
	}
1207

    
1208
	/* kill any running dhcrelay */
1209
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1210

    
1211
	$dhcrelaycfg =& $config['dhcrelay6'];
1212

    
1213
	/* DHCPv6 Relay enabled on any interfaces? */
1214
	if (!isset($dhcrelaycfg['enable']))
1215
		return 0;
1216

    
1217
	if ($g['booting'])
1218
		echo gettext("Starting DHCPv6 relay service...");
1219
	else
1220
		sleep(1);
1221

    
1222
	$iflist = get_configured_interface_list();
1223

    
1224
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1225
	foreach ($dhcifaces as $dhcrelayif) {
1226
		if (!isset($iflist[$dhcrelayif]) ||
1227
			link_interface_to_bridge($dhcrelayif))
1228
			continue;
1229

    
1230
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif)))
1231
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1232
	}
1233

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

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

    
1280
		if (!isset($destif)) {
1281
			if (is_array($config['gateways']['gateway_item'])) {
1282
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1283
					if (isset($gateway['defaultgw'])) {
1284
						$a_gateways = return_gateways_array(true);
1285
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1286
						break;
1287
					}
1288
				}
1289
			} else
1290
				$destif = get_real_interface("wan");
1291
		}
1292

    
1293
		if (!empty($destif))
1294
			$dhcrelayifs[] = $destif;
1295
	}
1296
	$dhcrelayifs = array_unique($dhcrelayifs);
1297

    
1298
	/* fire up dhcrelay */
1299
	if (empty($dhcrelayifs)) {
1300
		log_error("No suitable interface found for running dhcrelay -6!");
1301
		return; /* XXX */
1302
	}
1303

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

    
1306
	if (isset($dhcrelaycfg['agentoption']))
1307
		$cmd .=  " -a -m replace";
1308

    
1309
	$cmd .= " " . implode(" ", $srvips);
1310
	mwexec($cmd);
1311

    
1312
	return 0;
1313
}
1314

    
1315
function services_dyndns_configure_client($conf) {
1316

    
1317
	if (!isset($conf['enable']))
1318
		return;
1319

    
1320
	/* load up the dyndns.class */
1321
	require_once("dyndns.class");
1322

    
1323
	$dns = new updatedns($dnsService = $conf['type'],
1324
		$dnsHost = $conf['host'],
1325
		$dnsUser = $conf['username'],
1326
		$dnsPass = $conf['password'],
1327
		$dnsWilcard = $conf['wildcard'],
1328
		$dnsMX = $conf['mx'],
1329
		$dnsIf = "{$conf['interface']}",
1330
		$dnsBackMX = NULL,
1331
		$dnsServer = NULL,
1332
		$dnsPort = NULL,
1333
		$dnsUpdateURL = "{$conf['updateurl']}",
1334
		$forceUpdate = $conf['force'],
1335
                $dnsZoneID=$conf['zoneid'],
1336
                $dnsTTL=$conf['ttl'],
1337
		$dnsResultMatch = "{$conf['resultmatch']}",
1338
		$dnsRequestIf = "{$conf['requestif']}",
1339
		$dnsID = "{$conf['id']}");
1340
}
1341

    
1342
function services_dyndns_configure($int = "") {
1343
	global $config, $g;
1344
	if(isset($config['system']['developerspew'])) {
1345
		$mt = microtime();
1346
		echo "services_dyndns_configure() being called $mt\n";
1347
	}
1348

    
1349
	$dyndnscfg = $config['dyndnses']['dyndns'];
1350

    
1351
	if (is_array($dyndnscfg)) {
1352
		if ($g['booting'])
1353
			echo gettext("Starting DynDNS clients...");
1354

    
1355
		foreach ($dyndnscfg as $dyndns) {
1356
			if (!empty($int) && $int != $dyndns['interface'])
1357
				continue;
1358

    
1359
			services_dyndns_configure_client($dyndns);
1360

    
1361
			sleep(1);
1362
		}
1363

    
1364
		if ($g['booting'])
1365
			echo gettext("done.") . "\n";
1366
	}
1367

    
1368
	return 0;
1369
}
1370

    
1371
function services_dnsmasq_configure() {
1372
	global $config, $g;
1373
	$return = 0;
1374

    
1375
	if(isset($config['system']['developerspew'])) {
1376
		$mt = microtime();
1377
		echo "services_dnsmasq_configure() being called $mt\n";
1378
	}
1379

    
1380
	/* kill any running dnsmasq */
1381
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
1382
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1383

    
1384
	if (isset($config['dnsmasq']['enable'])) {
1385

    
1386
		if ($g['booting'])
1387
			echo gettext("Starting DNS forwarder...");
1388
		else
1389
			sleep(1);
1390

    
1391
		/* generate hosts file */
1392
		if(system_hosts_generate()!=0)
1393
			$return = 1;
1394

    
1395
		$args = "";
1396

    
1397
		if (isset($config['dnsmasq']['regdhcp'])) {
1398
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1399
		}
1400

    
1401
		/* Setup forwarded domains */
1402
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1403
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1404
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1405
			}
1406
		}
1407

    
1408
		/* Allow DNS Rebind for forwarded domains */
1409
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1410
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1411
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1412
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1413
				}
1414
			}
1415
		}
1416

    
1417
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1418
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1419

    
1420
		if ($config['dnsmasq']['custom_options']) {
1421
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1422
				$args .= " --$c";
1423
		}
1424

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

    
1428
		if ($g['booting'])
1429
			echo gettext("done.") . "\n";
1430
	}
1431

    
1432
	if (!$g['booting']) {
1433
		if(services_dhcpd_configure()!=0)
1434
			$return = 1;
1435
	}
1436

    
1437
	return $return;
1438
}
1439

    
1440
function services_unbound_configure() {
1441
	global $config, $g;
1442
	$return = 0;
1443

    
1444
	if(isset($config['system']['developerspew'])) {
1445
		$mt = microtime();
1446
		echo "services_unbound_configure() being called $mt\n";
1447
	}
1448

    
1449
	/* kill any running unbound */
1450
	sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1451

    
1452
	if (isset($config['unbound']['enable'])) {
1453

    
1454
		if ($g['booting'])
1455
			echo "Starting Unbound DNS...";
1456
		else
1457
			sleep(1);
1458

    
1459
		/* Setup Unbound DHCP Chroot environment */
1460
		$fd = fopen("{$g['tmp_path']}/unbound.sh","w");
1461
		$status = `/sbin/mount | /usr/bin/grep "{$g['unbound_chroot_path']}/dev"`;
1462
		fwrite($fd, "mkdir -p {$g['unbound_chroot_path']}\n");
1463
		fwrite($fd, "mkdir -p {$g['unbound_chroot_path']}/dev\n");
1464
		fwrite($fd, "mkdir -p {$g['unbound_chroot_path']}/etc\n");
1465
		if(!trim($status))
1466
			fwrite($fd, "mount -t devfs devfs {$g['unbound_chroot_path']}/dev\n");
1467
		fclose($fd);
1468
		mwexec("/bin/sh {$g['tmp_path']}/unbound.sh");
1469

    
1470
		/* generate Unbound config file */
1471
		if(unbound_generate_config()!=0) {
1472
			log_error("Problem generating Unbound configuration.");
1473
			$return = 1;
1474
		}
1475

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

    
1479
		if ($g['booting'])
1480
			echo "done.\n";
1481
	}
1482

    
1483
	return $return;
1484
}
1485

    
1486
function services_snmpd_configure() {
1487
	global $config, $g;
1488
	if(isset($config['system']['developerspew'])) {
1489
		$mt = microtime();
1490
		echo "services_snmpd_configure() being called $mt\n";
1491
	}
1492

    
1493
	/* kill any running snmpd */
1494
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1495
	sleep(2);
1496
	if(is_process_running("bsnmpd"))
1497
		mwexec("/usr/bin/killall bsnmpd", true);
1498

    
1499
	if (isset($config['snmpd']['enable'])) {
1500

    
1501
		if ($g['booting'])
1502
			echo gettext("Starting SNMP daemon... ");
1503

    
1504
		/* generate snmpd.conf */
1505
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1506
		if (!$fd) {
1507
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1508
			return 1;
1509
		}
1510

    
1511

    
1512
		$snmpdconf = <<<EOD
1513
location := "{$config['snmpd']['syslocation']}"
1514
contact := "{$config['snmpd']['syscontact']}"
1515
read := "{$config['snmpd']['rocommunity']}"
1516

    
1517
EOD;
1518

    
1519
/* No docs on what write strings do there for disable for now.
1520
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1521
		    $snmpdconf .= <<<EOD
1522
# write string
1523
write := "{$config['snmpd']['rwcommunity']}"
1524

    
1525
EOD;
1526
		}
1527
*/
1528

    
1529

    
1530
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1531
		    $snmpdconf .= <<<EOD
1532
# SNMP Trap support.
1533
traphost := {$config['snmpd']['trapserver']}
1534
trapport := {$config['snmpd']['trapserverport']}
1535
trap := "{$config['snmpd']['trapstring']}"
1536

    
1537

    
1538
EOD;
1539
		}
1540

    
1541

    
1542
		$snmpdconf .= <<<EOD
1543
system := 1     # pfSense
1544
%snmpd
1545
begemotSnmpdDebugDumpPdus       = 2
1546
begemotSnmpdDebugSyslogPri      = 7
1547
begemotSnmpdCommunityString.0.1 = $(read)
1548

    
1549
EOD;
1550

    
1551
/* No docs on what write strings do there for disable for now.
1552
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1553
		    $snmpdconf .= <<<EOD
1554
begemotSnmpdCommunityString.0.2 = $(write)
1555

    
1556
EOD;
1557
		}
1558
*/
1559

    
1560

    
1561
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1562
		    $snmpdconf .= <<<EOD
1563
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1564
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1565
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1566

    
1567
EOD;
1568
		}
1569

    
1570

    
1571
		$snmpdconf .= <<<EOD
1572
begemotSnmpdCommunityDisable    = 1
1573

    
1574
EOD;
1575

    
1576
		if (isset($config['snmpd']['bindlan'])) {
1577
			$config['snmpd']['bindip'] = 'lan';
1578
			unset($config['snmpd']['bindlan']);
1579
		}
1580
		$bind_to_ip = "0.0.0.0";
1581
		if(isset($config['snmpd']['bindip'])) {
1582
			if (is_ipaddr($config['snmpd']['bindip'])) {
1583
				$bind_to_ip = $config['snmpd']['bindip'];
1584
			} else {
1585
				$if = get_real_interface($config['snmpd']['bindip']);
1586
				if (does_interface_exist($if))
1587
					$bind_to_ip = find_interface_ip($if);
1588
			}
1589
		}
1590

    
1591
		if(is_port( $config['snmpd']['pollport'] )) {
1592
		    $snmpdconf .= <<<EOD
1593
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1594

    
1595
EOD;
1596

    
1597
		}
1598

    
1599
		$snmpdconf .= <<<EOD
1600
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1601
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1602

    
1603
# These are bsnmp macros not php vars.
1604
sysContact      = $(contact)
1605
sysLocation     = $(location)
1606
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1607

    
1608
snmpEnableAuthenTraps = 2
1609

    
1610
EOD;
1611

    
1612
		if (is_array( $config['snmpd']['modules'] )) {
1613
		    if(isset($config['snmpd']['modules']['mibii'])) {
1614
			$snmpdconf .= <<<EOD
1615
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1616

    
1617
EOD;
1618
		    }
1619

    
1620
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1621
			$snmpdconf .= <<<EOD
1622
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1623
%netgraph
1624
begemotNgControlNodeName = "snmpd"
1625

    
1626
EOD;
1627
		    }
1628

    
1629
		    if(isset($config['snmpd']['modules']['pf'])) {
1630
			$snmpdconf .= <<<EOD
1631
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1632

    
1633
EOD;
1634
		    }
1635

    
1636
		    if(isset($config['snmpd']['modules']['hostres'])) {
1637
			$snmpdconf .= <<<EOD
1638
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1639

    
1640
EOD;
1641
		    }
1642
		    if(isset($config['snmpd']['modules']['bridge'])) {
1643
			$snmpdconf .= <<<EOD
1644
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1645
# config must end with blank line
1646

    
1647

    
1648
EOD;
1649
		    }
1650
		}
1651

    
1652
		fwrite($fd, $snmpdconf);
1653
		fclose($fd);
1654

    
1655
		if (isset($config['snmpd']['bindlan'])) {
1656
			$bindlan = "";
1657
		}
1658

    
1659
		/* run bsnmpd */
1660
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1661
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1662

    
1663
		if ($g['booting'])
1664
			echo gettext("done.") . "\n";
1665
	}
1666

    
1667
	return 0;
1668
}
1669

    
1670
function services_dnsupdate_process($int = "") {
1671
	global $config, $g;
1672
	if(isset($config['system']['developerspew'])) {
1673
		$mt = microtime();
1674
		echo "services_dnsupdate_process() being called $mt\n";
1675
	}
1676

    
1677
	/* Dynamic DNS updating active? */
1678
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1679
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1680
			if (!isset($dnsupdate['enable']))
1681
				continue;
1682
			if (!empty($int) && $int != $dnsupdate['interface'])
1683
				continue;
1684

    
1685
			/* determine interface name */
1686
			$if = get_real_interface($dnsupdate['interface']);
1687
			$wanip = get_interface_ip($dnsupdate['interface']);
1688
			if ($wanip) {
1689

    
1690
				$keyname = $dnsupdate['keyname'];
1691
				/* trailing dot */
1692
				if (substr($keyname, -1) != ".")
1693
					$keyname .= ".";
1694

    
1695
				$hostname = $dnsupdate['host'];
1696
				/* trailing dot */
1697
				if (substr($hostname, -1) != ".")
1698
					$hostname .= ".";
1699

    
1700
				/* write private key file
1701
				   this is dumb - public and private keys are the same for HMAC-MD5,
1702
				   but nsupdate insists on having both */
1703
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1704
				$privkey = <<<EOD
1705
Private-key-format: v1.2
1706
Algorithm: 157 (HMAC)
1707
Key: {$dnsupdate['keydata']}
1708

    
1709
EOD;
1710
				fwrite($fd, $privkey);
1711
				fclose($fd);
1712

    
1713
				/* write public key file */
1714
				if ($dnsupdate['keytype'] == "zone") {
1715
					$flags = 257;
1716
					$proto = 3;
1717
				} else if ($dnsupdate['keytype'] == "host") {
1718
					$flags = 513;
1719
					$proto = 3;
1720
				} else if ($dnsupdate['keytype'] == "user") {
1721
					$flags = 0;
1722
					$proto = 2;
1723
				}
1724

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

    
1729
				/* generate update instructions */
1730
				$upinst = "";
1731
				if (!empty($dnsupdate['server']))
1732
					$upinst .= "server {$dnsupdate['server']}\n";
1733
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1734
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1735
				$upinst .= "\n";	/* mind that trailing newline! */
1736

    
1737
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1738
				fwrite($fd, $upinst);
1739
				fclose($fd);
1740

    
1741
				/* invoke nsupdate */
1742
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1743
				if (isset($dnsupdate['usetcp']))
1744
					$cmd .= " -v";
1745
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1746

    
1747
				mwexec_bg($cmd);
1748
			}
1749
		}
1750
	}
1751

    
1752
	return 0;
1753
}
1754

    
1755
function setup_wireless_olsr() {
1756
	global $config, $g;
1757
	if ($g['platform'] == 'jail' || !$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1758
		return;
1759
	if(isset($config['system']['developerspew'])) {
1760
		$mt = microtime();
1761
		echo "setup_wireless_olsr($interface) being called $mt\n";
1762
	}
1763
	conf_mount_rw();
1764
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1765
		$olsr_enable = $olsrd['enable'];
1766
		if($olsr_enable <> "on") {
1767
			if (is_process_running("olsrd"))
1768
				mwexec("/usr/bin/killall olsrd", true);
1769
			return;
1770
		}
1771
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1772

    
1773
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1774
			$enableannounce .= "\nHna4\n";
1775
			$enableannounce .= "{\n";
1776
		if($olsrd['announcedynamicroute'])
1777
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1778
		if($olsrd['enableannounce'] == "on")
1779
			$enableannounce .= "0.0.0.0 0.0.0.0";
1780
			$enableannounce .= "\n}\n";
1781
		} else {
1782
			$enableannounce = "";
1783
		}
1784

    
1785
		$olsr .= <<<EODA
1786
#
1787
# olsr.org OLSR daemon config file
1788
#
1789
# Lines starting with a # are discarded
1790
#
1791
# This file was generated by setup_wireless_olsr() in services.inc
1792
#
1793

    
1794
# This file is an example of a typical
1795
# configuration for a mostly static
1796
# network(regarding mobility) using
1797
# the LQ extention
1798

    
1799
# Debug level(0-9)
1800
# If set to 0 the daemon runs in the background
1801

    
1802
DebugLevel	2
1803

    
1804
# IP version to use (4 or 6)
1805

    
1806
IpVersion	4
1807

    
1808
# Clear the screen each time the internal state changes
1809

    
1810
ClearScreen     yes
1811

    
1812
{$enableannounce}
1813

    
1814
# Should olsrd keep on running even if there are
1815
# no interfaces available? This is a good idea
1816
# for a PCMCIA/USB hotswap environment.
1817
# "yes" OR "no"
1818

    
1819
AllowNoInt	yes
1820

    
1821
# TOS(type of service) value for
1822
# the IP header of control traffic.
1823
# If not set it will default to 16
1824

    
1825
#TosValue	16
1826

    
1827
# The fixed willingness to use(0-7)
1828
# If not set willingness will be calculated
1829
# dynamically based on battery/power status
1830
# if such information is available
1831

    
1832
#Willingness    	4
1833

    
1834
# Allow processes like the GUI front-end
1835
# to connect to the daemon.
1836

    
1837
IpcConnect
1838
{
1839
     # Determines how many simultaneously
1840
     # IPC connections that will be allowed
1841
     # Setting this to 0 disables IPC
1842

    
1843
     MaxConnections  0
1844

    
1845
     # By default only 127.0.0.1 is allowed
1846
     # to connect. Here allowed hosts can
1847
     # be added
1848

    
1849
     Host            127.0.0.1
1850
     #Host            10.0.0.5
1851

    
1852
     # You can also specify entire net-ranges
1853
     # that are allowed to connect. Multiple
1854
     # entries are allowed
1855

    
1856
     #Net             192.168.1.0 255.255.255.0
1857
}
1858

    
1859
# Wether to use hysteresis or not
1860
# Hysteresis adds more robustness to the
1861
# link sensing but delays neighbor registration.
1862
# Used by default. 'yes' or 'no'
1863

    
1864
UseHysteresis	no
1865

    
1866
# Hysteresis parameters
1867
# Do not alter these unless you know
1868
# what you are doing!
1869
# Set to auto by default. Allowed
1870
# values are floating point values
1871
# in the interval 0,1
1872
# THR_LOW must always be lower than
1873
# THR_HIGH.
1874

    
1875
#HystScaling	0.50
1876
#HystThrHigh	0.80
1877
#HystThrLow	0.30
1878

    
1879

    
1880
# Link quality level
1881
# 0 = do not use link quality
1882
# 1 = use link quality for MPR selection
1883
# 2 = use link quality for MPR selection and routing
1884
# Defaults to 0
1885

    
1886
LinkQualityLevel	{$olsrd['enablelqe']}
1887

    
1888
# Link quality window size
1889
# Defaults to 10
1890

    
1891
LinkQualityWinSize	10
1892

    
1893
# Polling rate in seconds(float).
1894
# Default value 0.05 sec
1895

    
1896
Pollrate	0.05
1897

    
1898

    
1899
# TC redundancy
1900
# Specifies how much neighbor info should
1901
# be sent in TC messages
1902
# Possible values are:
1903
# 0 - only send MPR selectors
1904
# 1 - send MPR selectors and MPRs
1905
# 2 - send all neighbors
1906
#
1907
# defaults to 0
1908

    
1909
TcRedundancy	2
1910

    
1911
#
1912
# MPR coverage
1913
# Specifies how many MPRs a node should
1914
# try select to reach every 2 hop neighbor
1915
#
1916
# Can be set to any integer >0
1917
#
1918
# defaults to 1
1919

    
1920
MprCoverage	3
1921

    
1922
# Example plugin entry with parameters:
1923

    
1924
EODA;
1925

    
1926
if($olsrd['enablehttpinfo'] == "on") {
1927
	$olsr .= <<<EODB
1928

    
1929
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1930
{
1931
    PlParam     "port"   "{$olsrd['port']}"
1932
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1933
}
1934

    
1935
EODB;
1936

    
1937
}
1938

    
1939
if($olsrd['enabledsecure'] == "on") {
1940
	$olsr .= <<<EODC
1941

    
1942
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1943
{
1944
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1945
}
1946

    
1947
EODC;
1948

    
1949
}
1950

    
1951
if($olsrd['enabledyngw'] == "on") {
1952

    
1953
	/* unset default route, olsr auto negotiates */
1954
	mwexec("/sbin/route delete default");
1955

    
1956
	$olsr .= <<<EODE
1957

    
1958
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1959
{
1960
    # how often to look for a inet gw, in seconds
1961
    # defaults to 5 secs, if commented out
1962
    PlParam     "Interval"   "{$olsrd['polling']}"
1963

    
1964
    # if one or more IPv4 addresses are given, do a ping on these in
1965
    # descending order to validate that there is not only an entry in
1966
    # routing table, but also a real internet connection. If any of
1967
    # these addresses could be pinged successfully, the test was
1968
    # succesful, i.e. if the ping on the 1st address was successful,the
1969
    # 2nd won't be pinged
1970
    PlParam     "Ping"       "{$olsrd['ping']}"
1971
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1972
}
1973

    
1974
EODE;
1975

    
1976
}
1977

    
1978
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1979
	$interfaces = explode(',', $conf['iface_array']);
1980
	foreach($interfaces as $interface) {
1981
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1982
$olsr .= <<<EODAD
1983
Interface "{$realinterface}"
1984
{
1985

    
1986
    # Hello interval in seconds(float)
1987
    HelloInterval    2.0
1988

    
1989
    # HELLO validity time
1990
    HelloValidityTime	20.0
1991

    
1992
    # TC interval in seconds(float)
1993
    TcInterval        5.0
1994

    
1995
    # TC validity time
1996
    TcValidityTime	30.0
1997

    
1998
    # MID interval in seconds(float)
1999
    MidInterval	5.0
2000

    
2001
    # MID validity time
2002
    MidValidityTime	30.0
2003

    
2004
    # HNA interval in seconds(float)
2005
    HnaInterval	5.0
2006

    
2007
    # HNA validity time
2008
    HnaValidityTime 	30.0
2009

    
2010
    # When multiple links exist between hosts
2011
    # the weight of interface is used to determine
2012
    # the link to use. Normally the weight is
2013
    # automatically calculated by olsrd based
2014
    # on the characteristics of the interface,
2015
    # but here you can specify a fixed value.
2016
    # Olsrd will choose links with the lowest value.
2017

    
2018
    # Weight 0
2019

    
2020

    
2021
}
2022

    
2023
EODAD;
2024

    
2025
	}
2026
	break;
2027
}
2028
		fwrite($fd, $olsr);
2029
		fclose($fd);
2030
	}
2031

    
2032
	if (is_process_running("olsrd"))
2033
		mwexec("/usr/bin/killall olsrd", true);
2034

    
2035
	sleep(2);
2036

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

    
2039
	conf_mount_ro();
2040
}
2041

    
2042
/* configure cron service */
2043
function configure_cron() {
2044
	global $g, $config;
2045

    
2046
	conf_mount_rw();
2047
	/* preserve existing crontab entries */
2048
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2049

    
2050
	for ($i = 0; $i < count($crontab_contents); $i++) {
2051
		$cron_item =& $crontab_contents[$i];
2052
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
2053
			array_splice($crontab_contents, $i - 1);
2054
			break;
2055
		}
2056
	}
2057
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
2058

    
2059

    
2060
	if (is_array($config['cron']['item'])) {
2061
		$crontab_contents .= "#\n";
2062
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2063
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
2064
		$crontab_contents .= "#\n";
2065

    
2066
		foreach ($config['cron']['item'] as $item) {
2067
			$crontab_contents .= "\n{$item['minute']}\t";
2068
			$crontab_contents .= "{$item['hour']}\t";
2069
			$crontab_contents .= "{$item['mday']}\t";
2070
			$crontab_contents .= "{$item['month']}\t";
2071
			$crontab_contents .= "{$item['wday']}\t";
2072
			$crontab_contents .= "{$item['who']}\t";
2073
			$crontab_contents .= "{$item['command']}";
2074
		}
2075

    
2076
		$crontab_contents .= "\n#\n";
2077
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2078
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2079
		$crontab_contents .= "#\n\n";
2080
	}
2081

    
2082
	/* please maintain the newline at the end of file */
2083
	file_put_contents("/etc/crontab", $crontab_contents);
2084

    
2085
	/* do a HUP kill to force sync changes */
2086
	exec('/bin/pkill -HUP cron');
2087

    
2088
	conf_mount_ro();
2089
}
2090

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

    
2114
function upnp_start() {
2115
	global $config;
2116

    
2117
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2118
		return;
2119

    
2120
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2121
		echo gettext("Starting UPnP service... ");
2122
		require_once('/usr/local/pkg/miniupnpd.inc');
2123
		sync_package_miniupnpd();
2124
		echo "done.\n";
2125
	}
2126
}
2127

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

    
2131
	$is_installed = false;
2132

    
2133
	if(!$config['cron']['item'])
2134
		return;
2135

    
2136
	$x=0;
2137
	foreach($config['cron']['item'] as $item) {
2138
		if(strstr($item['command'], $command)) {
2139
			$is_installed = true;
2140
			break;
2141
		}
2142
		$x++;
2143
	}
2144

    
2145
	if($active) {
2146
		$cron_item = array();
2147
		$cron_item['minute'] = $minute;
2148
		$cron_item['hour'] = $hour;
2149
		$cron_item['mday'] = $monthday;
2150
		$cron_item['month'] = $month;
2151
		$cron_item['wday'] = $weekday;
2152
		$cron_item['who'] = $who;
2153
		$cron_item['command'] = $command;
2154
		if(!$is_installed) {
2155
			$config['cron']['item'][] = $cron_item;
2156
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
2157
		} else {
2158
			$config['cron']['item'][$x] = $cron_item;
2159
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
2160
		}
2161
	} else {
2162
		if(($is_installed == true) && ($x > 0)) {
2163
			unset($config['cron']['item'][$x]);
2164
			write_config(sprintf(gettext("Remvoed cron job for %s"), $command));
2165
		}
2166
	}
2167
	configure_cron();
2168
}
2169

    
2170
?>
(48-48/66)