Project

General

Profile

Download (58.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_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
		/* are router advertisements enabled? */
88
		if($dhcpv6ifconf['mode'] == "disabled")
89
			continue;
90
			
91
		$realif = get_real_interface($dhcpv6if);
92
		$radvdifs[] = $realif;
93

    
94
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
95
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
96
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
97
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
98

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

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

    
168
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
169
	foreach ($Iflist as $if => $ifdescr) {
170
		if((!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id'])) && (!is_numeric($config['interfaces'][$if]['prefix-6rd-id'])))
171
			continue;
172
			
173
		$realif = get_real_interface($if);
174
		/* prevent duplicate entries, manual overrides */
175
		if(in_array($realif, $radvdifs))
176
			continue;
177

    
178
		$radvdifs[] = $realif;
179

    
180
		$ifcfgipv6 = get_interface_ipv6($if);
181
		$ifcfgsnv6 = get_interface_subnetv6($if);
182
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
183
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
184
		$autotype = "DHCP-PD";
185
		/* 6rd on this interface? */
186
		if(is_numeric($config['interfaces'][$if]['prefix-6rd-id'])) {
187
			/* find the interface which has the 6RD prefix defined and it's IPv4 address */
188
			foreach($Iflist as $rdif => $rdifdescr) {
189
				if($config['interfaces'][$rdif]['ipaddrv6'] == "6rd") {
190
					$realrdif = get_real_interface("$rdif");
191
					$ip4address = find_interface_ip($realrdif);
192
					log_error("radvd config found 6RD if {$rdif} address {$ip4address} for interface {$if}");
193
					if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
194
						log_error("The interface IPv4 '{$ip4address}' address on interface '{$rdif}' is not public, not configuring 6RD prefix on {$if}");
195
						// continue;
196
					}
197
					/* calculate the IPv6 prefix from the public IPv4 address */
198
					$ip4arr = explode(".", $ip4address);
199
					$rd6prefix = explode("/", $config['interfaces'][$rdif]['prefix-6rd']);
200
					$rd6prefix = explode(":", $rd6prefix[0]);
201
					$rd6lanprefixlen = 64;
202
					$rd6lanprefix = sprintf("{$rd6prefix[0]}:{$rd6prefix[1]}:%02x%02x:%02x%02x::", $ip4arr[0], $ip4arr[1], $ip4arr[2], $ip4arr[3]);
203
					$ifcfgsnv6 = "{$rd6lanprefixlen}";
204
					$subnetv6 = "{$rd6lanprefix}";
205
					$autotype = "6rd";
206
					break;
207
				}
208
			}
209
		}
210
		
211
		log_error("configuring interface {$if} for type {$autotype} radvd subnet {$subnetv6}/{$ifcfgsnv6}");
212

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

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

    
251
	fwrite($fd, $radvdconf);
252
	fclose($fd);
253

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

    
260
function services_dhcpd_configure() {
261
	global $config, $g;
262

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

    
284
	services_dhcpdv4_configure();
285
	services_dhcpdv6_configure();
286
	services_radvd_configure();
287
	return;
288

    
289
}
290
function services_dhcpdv4_configure() {
291
	global $config, $g;
292

    
293
	if($g['services_dhcp_server_enable'] == false)
294
		return;
295

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

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

    
306
	/* DHCP enabled on any interfaces? */
307
	if (!is_dhcp_server_enabled())
308
		return 0;
309

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

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

    
331
	$syscfg = $config['system'];
332
	if (!is_array($config['dhcpd']))
333
		$config['dhcpd'] = array();
334
	$dhcpdcfg = $config['dhcpd'];
335
	$Iflist = get_configured_interface_list();
336

    
337
	if ($g['booting'])
338
		echo gettext("Starting DHCP service...");
339
	else
340
		sleep(1);
341

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

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

    
362
	$dhcpdconf = <<<EOD
363

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

    
376
EOD;
377

    
378
	if(!isset($dhcpifconf['disableauthoritative']))
379
		$dhcpdconf .= "authoritative;\n";
380

    
381
	if(isset($dhcpifconf['alwaysbroadcast']))
382
		$dhcpdconf .= "always-broadcast on\n";
383

    
384
	$dhcpdifs = array();
385

    
386
	/*    loop through and determine if we need to setup
387
	 *    failover peer "bleh" entries
388
	 */
389
	$dhcpnum = 0;
390
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
391

    
392
		interfaces_staticarp_configure($dhcpif);
393

    
394
		if (!isset($dhcpifconf['enable']))
395
			continue;
396

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

    
443
EOPP;
444
		$dhcpnum++;
445
		}
446
	}
447

    
448
	$dhcpnum = 0;
449

    
450
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
451

    
452
		$ifcfg = $config['interfaces'][$dhcpif];
453

    
454
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
455
			continue;
456
		$ifcfgip = get_interface_ip($dhcpif);
457
		$ifcfgsn = get_interface_subnet($dhcpif);
458
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
459
		$subnetmask = gen_subnet_mask($ifcfgsn);
460

    
461
		if (!is_ipaddr($subnet))
462
			continue;
463

    
464
		if($is_olsr_enabled == true)
465
			if($dhcpifconf['netmask'])
466
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
467

    
468
		$dnscfg = "";
469

    
470
		if ($dhcpifconf['domain']) {
471
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
472
		}
473

    
474
    		if($dhcpifconf['domainsearchlist'] <> "") {
475
			$dnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpifconf['domainsearchlist'])) . "\";\n";
476
                        $domains = implode(',', array_map(strify, explode(' ', $dhcpifconf['domainsearchlist'])));
477
                        $dnscfg .= "   option domain-search {$domains};\n";
478
    		}
479

    
480
		if (isset($dhcpifconf['ddnsupdate'])) {
481
			if($dhcpifconf['ddnsdomain'] <> "") {
482
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
483
			}
484
			$dnscfg .= "	ddns-update-style interim;\n";
485
		}
486

    
487
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
488
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
489
		} else if (isset($config['dnsmasq']['enable'])) {
490
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
491
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
492
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
493
		}
494

    
495
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
496
		$dhcpdconf .= "	pool {\n";
497

    
498
		/* is failover dns setup? */
499
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
500
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
501
			if($dhcpifconf['dnsserver'][1] <> "")
502
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
503
			$dhcpdconf .= ";\n";
504
		}
505

    
506
		if($dhcpifconf['failover_peerip'] <> "")
507
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
508

    
509
		if (isset($dhcpifconf['denyunknown']))
510
		   $dhcpdconf .= "		deny unknown-clients;\n";
511

    
512
		if ($dhcpifconf['gateway'])
513
			$routers = $dhcpifconf['gateway'];
514
		else
515
			$routers = $ifcfgip;
516

    
517
		if($dhcpifconf['failover_peerip'] <> "") {
518
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
519
			$dhcpnum++;
520
		}
521

    
522
		$dhcpdconf .= <<<EOD
523
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
524
	}
525
	option routers {$routers};
526
$dnscfg
527

    
528
EOD;
529
    		// default-lease-time
530
		if ($dhcpifconf['defaultleasetime'])
531
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
532

    
533
		// max-lease-time
534
		if ($dhcpifconf['maxleasetime'])
535
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
536

    
537
		// netbios-name*
538
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
539
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
540
			$dhcpdconf .= "	option netbios-node-type 8;\n";
541
		}
542

    
543
		// ntp-servers
544
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
545
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
546

    
547
		// tftp-server-name
548
		if ($dhcpifconf['tftp'] <> "")
549
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
550

    
551
		// Handle option, number rowhelper values
552
		$dhcpdconf .= "\n";
553
		if($dhcpifconf['numberoptions']['item']) {
554
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
555
				if(empty($item['type']) || $item['type'] == "text")
556
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
557
				else
558
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
559
			}
560
		}
561

    
562
		// ldap-server
563
		if ($dhcpifconf['ldap'] <> "")
564
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
565

    
566
		// net boot information
567
		if(isset($dhcpifconf['netboot'])) {
568
			if ($dhcpifconf['nextserver'] <> "") {
569
				$dhcpdconf .= "	next-server {$dhcpifconf['nextserver']};\n";
570
			}
571
			if ($dhcpifconf['filename'] <> "") {
572
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
573
			}
574
			if ($dhcpifconf['rootpath'] <> "") {
575
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
576
      		}
577
		}
578

    
579
		$dhcpdconf .= <<<EOD
580
}
581

    
582
EOD;
583

    
584
		/* add static mappings */
585
		if (is_array($dhcpifconf['staticmap'])) {
586

    
587
			$i = 0;
588
			foreach ($dhcpifconf['staticmap'] as $sm) {
589
				$dhcpdconf .= <<<EOD
590
host s_{$dhcpif}_{$i} {
591
	hardware ethernet {$sm['mac']};
592

    
593
EOD;
594
				if ($sm['ipaddr'])
595
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
596

    
597
				if ($sm['hostname']) {
598
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
599
					$dhhostname = str_replace(".", "_", $dhhostname);
600
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
601
				}
602
				if ($sm['filename'])
603
					$dhcpdconf .= "	filename \"{$sm['filename']}\";\n";
604

    
605
				if ($sm['rootpath'])
606
					$dhcpdconf .= "	option root-path \"{$sm['rootpath']}\";\n";
607

    
608
				$dhcpdconf .= "}\n";
609
				$i++;
610
			}
611
		}
612

    
613
		$dhcpdifs[] = get_real_interface($dhcpif);
614
	}
615

    
616
	fwrite($fd, $dhcpdconf);
617
	fclose($fd);
618

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

    
622

    
623
	/* fire up dhcpd in a chroot */
624
	if(count($dhcpdifs) > 0) {
625
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
626
			join(" ", $dhcpdifs));
627
	}
628

    
629
	if ($g['booting']) {
630
		print "done.\n";
631
	}
632

    
633
	return 0;
634
}
635

    
636
function services_dhcpdv6_configure() {
637
	global $config, $g;
638

    
639
	if($g['services_dhcp_server_enable'] == false)
640
		return;
641

    
642
	if(isset($config['system']['developerspew'])) {
643
		$mt = microtime();
644
		echo "services_dhcpd_configure($if) being called $mt\n";
645
	}
646

    
647
	/* kill any running dhcpd */
648
	if(is_process_running("dhcpd")) {
649
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
650
	}
651

    
652
	/* DHCP enabled on any interfaces? */
653
	if (!is_dhcp_server_enabled())
654
		return 0;
655

    
656
	/* if OLSRD is enabled, allow WAN to house DHCP. */
657
	if($config['installedpackages']['olsrd'])
658
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
659
				if($olsrd['enable'])
660
					$is_olsr_enabled = true;
661

    
662
	if ($g['booting']) {
663
		if ($g['platform'] != "pfSense") {
664
			/* restore the leases, if we have them */
665
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
666
				$dhcprestore = "";
667
				$dhcpreturn = "";
668
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
669
				$dhcprestore = implode(" ", $dhcprestore);
670
				if($dhcpreturn <> 0) {
671
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
672
				}
673
			}
674
		}
675
	}
676

    
677
	$syscfg = $config['system'];
678
	if (!is_array($config['dhcpdv6']))
679
		$config['dhcpdv6'] = array();
680
	$dhcpdv6cfg = $config['dhcpdv6'];
681
	$Iflist = get_configured_interface_list();
682

    
683
	if ($g['booting'])
684
		echo "Starting DHCPv6 service...";
685
	else
686
		sleep(1);
687

    
688
	/* write dhcpdv6.conf */
689
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
690
	if (! $fdv6) {
691
		printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n");
692
		return 1;
693
	}
694

    
695
	$custoptionsv6 = "";
696
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
697
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
698
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
699
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
700
			}
701
		}
702
	}
703

    
704
	$dhcpdv6conf = <<<EOD
705

    
706
option domain-name "{$syscfg['domain']}";
707
option ldap-server code 95 = text;
708
option domain-search-list code 119 = text;
709
{$custoptions}
710
default-lease-time 7200;
711
max-lease-time 86400;
712
log-facility local7;
713
ddns-update-style none;
714
one-lease-per-client true;
715
deny duplicates;
716
ping-check true;
717

    
718
EOD;
719

    
720
	if(!isset($dhcpv6ifconf['disableauthoritative']))
721
		$dhcpdv6conf .= "authoritative;\n";
722

    
723
	if(isset($dhcpv6ifconf['alwaysbroadcast']))
724
		$dhcpdv6conf .= "always-broadcast on\n";
725

    
726
	$dhcpdv6ifs = array();
727

    
728
	/*    loop through and determine if we need to setup
729
	 *    failover peer "bleh" entries
730
	 */
731
	$dhcpv6num = 0;
732
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
733

    
734
		if (!isset($dhcpv6ifconf['enable']))
735
			continue;
736

    
737
		if($dhcpv6ifconf['failover_peerip'] <> "") {
738
			$intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']);
739
			$intipv6 = find_interface_ipv6($intv6);
740
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
741
			/*
742
			 *    yep, failover peer is defined.
743
			 *    does it match up to a defined vip?
744
			 */
745
			$skew = 110;
746
			$a_vip = &$config['virtualip']['vip'];
747
			if(is_array($a_vip)) {
748
				foreach ($a_vip as $vipent) {
749
					if($intv6 == $real_dhcpv6if) {
750
						/* this is the interface! */
751
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
752
							$skew = 0;
753
					}
754
				}
755
			} else {
756
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
757
			}
758
			if($skew > 10) {
759
				$typev6 = "secondary";
760
				$dhcpdv6conf_pri  = "mclt 600;\n";
761
				$my_portv6 = "520";
762
				$peer_portv6 = "519";
763
			} else {
764
				$my_portv6 = "519";
765
				$peer_portv6 = "520";
766
				$typev6 = "primary";
767
				$dhcpdv6conf_pri  = "split 128;\n";
768
				$dhcpdv6conf_pri .= "  mclt 600;\n";
769
			}
770
			$dhcpdv6conf .= <<<EOPP
771
failover peer "dhcpv6{$dhcpv6num}" {
772
  {$typev6};
773
  address {$intipv6};
774
  port {$my_portv6};
775
  peer address {$dhcpv6ifconf['failover_peerip']};
776
  peer port {$peer_portv6};
777
  max-response-delay 10;
778
  max-unacked-updates 10;
779
  {$dhcpdv6conf_pri}
780
  load balance max seconds 3;
781
}
782

    
783
EOPP;
784
		$dhcpv6num++;
785
		}
786
	}
787

    
788
	$dhcpv6num = 0;
789
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
790

    
791
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
792

    
793
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
794
			continue;
795
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
796
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
797
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
798
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
799

    
800
		if($is_olsr_enabled == true)
801
			if($dhcpv6ifconf['netmask'])
802
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
803

    
804
		$dnscfgv6 = "";
805

    
806
		if ($dhcpv6ifconf['domain']) {
807
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
808
		}
809

    
810
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
811
			$dnscfgv6 .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpv6ifconf['domainsearchlist'])) . "\";\n";
812
    		}
813

    
814
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
815
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
816
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
817
			}
818
			$dnscfgv6 .= "	ddns-update-style interim;\n";
819
		}
820

    
821
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
822
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
823
		} else if (isset($config['dnsmasq']['enable'])) {
824
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
825
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
826
			$dns_arrv6 = array();
827
			foreach($syscfg['dnsserver'] as $dnsserver) {
828
				if(is_ipaddrv6($dnsserver)) {
829
					$dns_arrv6[] = $dnsserver;
830
				}
831
			}
832
			if(!empty($dns_arrv6))
833
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
834
		}
835

    
836
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
837
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
838

    
839
		/* is failover dns setup? */
840
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
841
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
842
			if($dhcpv6ifconf['dnsserver'][1] <> "")
843
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
844
			$dhcpdv6conf .= ";\n";
845
		}
846

    
847
		if($dhcpv6ifconf['failover_peerip'] <> "")
848
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
849

    
850
		if (isset($dhcpv6ifconf['denyunknown']))
851
		   $dhcpdv6conf .= "		deny unknown-clients;\n";
852

    
853
		if($dhcpv6ifconf['failover_peerip'] <> "") {
854
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
855
			$dhcpv6num++;
856
		}
857

    
858
		$dhcpdv6conf .= <<<EOD
859
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
860
$dnscfgv6
861

    
862
EOD;
863

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

    
867
		}
868
    		// default-lease-time
869
		if ($dhcpv6ifconf['defaultleasetime'])
870
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
871

    
872
		// max-lease-time
873
		if ($dhcpv6ifconf['maxleasetime'])
874
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
875

    
876
		// ntp-servers
877
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) {
878
			$ntpservers = array();
879
			foreach($dhcpv6ifconf['ntpserver'] as $ntpserver) {
880
				if(is_ipaddrv6($ntpserver))
881
					$ntpservers[] = $ntpserver;
882
			}
883
			if(count($ntpservers) > 0 )
884
				$dhcpdv6conf .= "       option dhcp6.sntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
885
		}
886
		// tftp-server-name
887
		/* Needs ISC DHCPD support
888
		 if ($dhcpv6ifconf['tftp'] <> "")
889
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
890
		*/
891

    
892
		// Handle option, number rowhelper values
893
		$dhcpdv6conf .= "\n";
894
		if($dhcpv6ifconf['numberoptions']['item']) {
895
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
896
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
897
			}
898
		}
899

    
900
		// ldap-server
901
		if ($dhcpv6ifconf['ldap'] <> "")
902
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
903

    
904
		// net boot information
905
		if(isset($dhcpv6ifconf['netboot'])) {
906
			if ($dhcpv6ifconf['nextserver'] <> "") {
907
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['nextserver']};\n";
908
			}
909
			if ($dhcpv6ifconf['filename'] <> "") {
910
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
911
			}
912
			if ($dhcpv6ifconf['rootpath'] <> "") {
913
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
914
      		}
915
	}
916

    
917
		$dhcpdv6conf .= <<<EOD
918
}
919

    
920
EOD;
921

    
922
		/* add static mappings */
923
		/* Needs to use DUID */
924
		if (is_array($dhcpv6ifconf['staticmap'])) {
925

    
926
			$i = 0;
927
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
928
				$dhcpdv6conf .= <<<EOD
929
host s_{$dhcpv6if}_{$i} {
930
	host-identifier option dhcp6.client-id {$sm['duid']};
931

    
932
EOD;
933
				if ($sm['ipaddrv6'])
934
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
935

    
936
				if ($sm['hostname']) {
937
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
938
					$dhhostname = str_replace(".", "_", $dhhostname);
939
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
940
				}
941
				if ($sm['filename'])
942
					$dhcpdv6conf .= "	filename \"{$sm['filename']}\";\n";
943

    
944
				if ($sm['rootpath'])
945
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
946

    
947
				$dhcpdv6conf .= "}\n";
948
				$i++;
949
			}
950
		}
951

    
952
		if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") {
953
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
954
			$dhcpdv6ifs[] = $realif;
955
			exec("/sbin/ifconfig {$realif} |awk  '/ether/ {print $2}'", $mac);
956
			$v6address = generate_ipv6_from_mac($mac[0]);
957
			/* Create link local address for bridges */
958
			if(stristr("$realif", "bridge")) {
959
				mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
960
			}
961
		}
962
	}
963

    
964
	fwrite($fdv6, $dhcpdv6conf);
965
	fclose($fdv6);
966
	/* create an empty leases v6 database */
967
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
968

    
969

    
970
	/* fire up dhcpd in a chroot */
971
	if(count($dhcpdv6ifs) > 0) {
972
		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 " .
973
			join(" ", $dhcpdv6ifs));
974
	}
975

    
976
	if ($g['booting']) {
977
		print gettext("done.") . "\n";
978
	}
979

    
980
	return 0;
981
}
982

    
983
function services_igmpproxy_configure() {
984
        global $config, $g;
985

    
986
        /* kill any running igmpproxy */
987
        killbyname("igmpproxy");
988

    
989
	if (!is_array($config['igmpproxy']['igmpentry']))
990
		return 1;
991

    
992
        $iflist = get_configured_interface_list();
993

    
994
        $igmpconf = <<<EOD
995

    
996
##------------------------------------------------------
997
## Enable Quickleave mode (Sends Leave instantly)
998
##------------------------------------------------------
999
quickleave
1000

    
1001
EOD;
1002

    
1003
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
1004
                unset($iflist[$igmpcf['ifname']]);
1005
                $realif = get_real_interface($igmpcf['ifname']);
1006
                if (empty($igmpcf['threshold']))
1007
                        $threshld = 1;
1008
                else
1009
                        $threshld = $igmpcf['threshold'];
1010
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
1011

    
1012
                if ($igmpcf['address'] <> "") {
1013
                        $item = explode(" ", $igmpcf['address']);
1014
                        foreach($item as $iww)
1015
                                $igmpconf .= "altnet {$iww}\n";
1016
                }
1017
                $igmpconf .= "\n";
1018
        }
1019
        foreach ($iflist as $ifn) {
1020
                $realif = get_real_interface($ifn);
1021
                $igmpconf .= "phyint {$realif} disabled\n";
1022
        }
1023
	$igmpconf .= "\n";
1024

    
1025
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
1026
        if (!$igmpfl) {
1027
                log_error(gettext("Could not write Igmpproxy configuration file!"));
1028
                return;
1029
        }
1030
        fwrite($igmpfl, $igmpconf);
1031
        fclose($igmpfl);
1032

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

    
1036
        return 0;
1037
}
1038

    
1039
function services_dhcrelay_configure() {
1040
	global $config, $g;
1041
	if ($g['platform'] == 'jail')
1042
		return;
1043
	if(isset($config['system']['developerspew'])) {
1044
		$mt = microtime();
1045
		echo "services_dhcrelay_configure() being called $mt\n";
1046
	}
1047

    
1048
	/* kill any running dhcrelay */
1049
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1050

    
1051
	$dhcrelaycfg =& $config['dhcrelay'];
1052

    
1053
	/* DHCPRelay enabled on any interfaces? */
1054
	if (!isset($dhcrelaycfg['enable']))
1055
		return 0;
1056

    
1057
	if ($g['booting'])
1058
		echo gettext("Starting DHCP relay service...");
1059
	else
1060
		sleep(1);
1061

    
1062
	$iflist = get_configured_interface_list();
1063

    
1064
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1065
	foreach ($dhcifaces as $dhcrelayif) {
1066
		if (!isset($iflist[$dhcrelayif]) ||
1067
			link_interface_to_bridge($dhcrelayif))
1068
			continue;
1069

    
1070
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
1071
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1072
	}
1073

    
1074
	/*
1075
	 * In order for the relay to work, it needs to be active
1076
	 * on the interface in which the destination server sits.
1077
	 */
1078
	$srvips = explode(",", $dhcrelaycfg['server']);
1079
	foreach ($srvips as $srcidx => $srvip) {
1080
		unset($destif);
1081
		foreach ($iflist as $ifname) {
1082
			$subnet = get_interface_ip($ifname);
1083
			if (!is_ipaddr($subnet))
1084
				continue;
1085
			$subnet .=  "/" . get_interface_subnet($ifname);
1086
			if (ip_in_subnet($srvip, $subnet)) {
1087
				$destif = get_real_interface($ifname);
1088
				break;
1089
			}
1090
		}
1091
		if (!isset($destif)) {
1092
			if (is_array($config['staticroutes']['route'])) {
1093
				foreach ($config['staticroutes']['route'] as $rtent) {
1094
					if (ip_in_subnet($srvip, $rtent['network'])) {
1095
						$a_gateways = return_gateways_array(true);
1096
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1097
						break;
1098
					}
1099
				}
1100
			}
1101
		}
1102

    
1103
		if (!isset($destif)) {
1104
			/* Create a array from the existing route table */
1105
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
1106
        		array_shift($route_str);
1107
        		array_shift($route_str);
1108
        		array_shift($route_str);
1109
        		array_shift($route_str);
1110
        		$route_arr = array();
1111
        		foreach($route_str as $routeline) {
1112
                		$items = preg_split("/[ ]+/i", $routeline);
1113
				if (ip_in_subnet($srvip, $items[0])) {
1114
					$destif = trim($items[6]);
1115
					break;
1116
				}
1117
        		}
1118
		}
1119

    
1120
		if (!isset($destif)) {
1121
			if (is_array($config['gateways']['gateway_item'])) {
1122
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1123
					if (isset($gateway['defaultgw'])) {
1124
						$a_gateways = return_gateways_array(true);
1125
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1126
						break;
1127
					}
1128
				}
1129
			} else
1130
				$destif = get_real_interface("wan");
1131
		}
1132

    
1133
		if (!empty($destif))
1134
			$dhcrelayifs[] = $destif;
1135
	}
1136
	$dhcrelayifs = array_unique($dhcrelayifs);
1137

    
1138
	/* fire up dhcrelay */
1139
	if (empty($dhcrelayifs)) {
1140
		log_error("No suitable interface found for running dhcrelay!");
1141
		return; /* XXX */
1142
	}
1143

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

    
1146
	if (isset($dhcrelaycfg['agentoption']))
1147
		$cmd .=  " -a -m replace";
1148

    
1149
	$cmd .= " " . implode(" ", $srvips);
1150
	mwexec($cmd);
1151

    
1152
	return 0;
1153
}
1154

    
1155
function services_dhcrelay6_configure() {
1156
	global $config, $g;
1157
	if ($g['platform'] == 'jail')
1158
		return;
1159
	if(isset($config['system']['developerspew'])) {
1160
		$mt = microtime();
1161
		echo "services_dhcrelay_configure() being called $mt\n";
1162
	}
1163

    
1164
	/* kill any running dhcrelay */
1165
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1166

    
1167
	$dhcrelaycfg =& $config['dhcrelay6'];
1168

    
1169
	/* DHCPv6 Relay enabled on any interfaces? */
1170
	if (!isset($dhcrelaycfg['enable']))
1171
		return 0;
1172

    
1173
	if ($g['booting'])
1174
		echo gettext("Starting DHCPv6 relay service...");
1175
	else
1176
		sleep(1);
1177

    
1178
	$iflist = get_configured_interface_list();
1179

    
1180
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1181
	foreach ($dhcifaces as $dhcrelayif) {
1182
		if (!isset($iflist[$dhcrelayif]) ||
1183
			link_interface_to_bridge($dhcrelayif))
1184
			continue;
1185

    
1186
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif)))
1187
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1188
	}
1189

    
1190
	/*
1191
	 * In order for the relay to work, it needs to be active
1192
	 * on the interface in which the destination server sits.
1193
	 */
1194
	$srvips = explode(",", $dhcrelaycfg['server']);
1195
	foreach ($srvips as $srcidx => $srvip) {
1196
		unset($destif);
1197
		foreach ($iflist as $ifname) {
1198
			$subnet = get_interface_ipv6($ifname);
1199
			if (!is_ipaddrv6($subnet))
1200
				continue;
1201
			$subnet .=  "/" . get_interface_subnetv6($ifname);
1202
			if (ip_in_subnet($srvip, $subnet)) {
1203
				$destif = get_real_interface($ifname);
1204
				break;
1205
			}
1206
		}
1207
		if (!isset($destif)) {
1208
			if (is_array($config['staticroutes']['route'])) {
1209
				foreach ($config['staticroutes']['route'] as $rtent) {
1210
					if (ip_in_subnet($srvip, $rtent['network'])) {
1211
						$a_gateways = return_gateways_array(true);
1212
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1213
						break;
1214
					}
1215
				}
1216
			}
1217
		}
1218

    
1219
		if (!isset($destif)) {
1220
			/* Create a array from the existing route table */
1221
        		exec("/usr/bin/netstat -rnWf inet6", $route_str);
1222
        		array_shift($route_str);
1223
        		array_shift($route_str);
1224
        		array_shift($route_str);
1225
        		array_shift($route_str);
1226
        		$route_arr = array();
1227
        		foreach($route_str as $routeline) {
1228
                		$items = preg_split("/[ ]+/i", $routeline);
1229
				if (ip_in_subnet($srvip, $items[0])) {
1230
					$destif = trim($items[6]);
1231
					break;
1232
				}
1233
        		}
1234
		}
1235

    
1236
		if (!isset($destif)) {
1237
			if (is_array($config['gateways']['gateway_item'])) {
1238
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1239
					if (isset($gateway['defaultgw'])) {
1240
						$a_gateways = return_gateways_array(true);
1241
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
1242
						break;
1243
					}
1244
				}
1245
			} else
1246
				$destif = get_real_interface("wan");
1247
		}
1248

    
1249
		if (!empty($destif))
1250
			$dhcrelayifs[] = $destif;
1251
	}
1252
	$dhcrelayifs = array_unique($dhcrelayifs);
1253

    
1254
	/* fire up dhcrelay */
1255
	if (empty($dhcrelayifs)) {
1256
		log_error("No suitable interface found for running dhcrelay -6!");
1257
		return; /* XXX */
1258
	}
1259

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

    
1262
	if (isset($dhcrelaycfg['agentoption']))
1263
		$cmd .=  " -a -m replace";
1264

    
1265
	$cmd .= " " . implode(" ", $srvips);
1266
	mwexec($cmd);
1267

    
1268
	return 0;
1269
}
1270

    
1271
function services_dyndns_configure_client($conf) {
1272

    
1273
	if (!isset($conf['enable']))
1274
		return;
1275

    
1276
	/* load up the dyndns.class */
1277
	require_once("dyndns.class");
1278

    
1279
	$dns = new updatedns($dnsService = $conf['type'],
1280
		$dnsHost = $conf['host'],
1281
		$dnsUser = $conf['username'],
1282
		$dnsPass = $conf['password'],
1283
		$dnsWilcard = $conf['wildcard'],
1284
		$dnsMX = $conf['mx'],
1285
		$dnsIf = "{$conf['interface']}",
1286
		$dnsBackMX = NULL,
1287
		$dnsServer = NULL,
1288
		$dnsPort = NULL,
1289
		$dnsUpdateURL = NULL,
1290
		$forceUpdate = $conf['force']);
1291
}
1292

    
1293
function services_dyndns_configure($int = "") {
1294
	global $config, $g;
1295
	if(isset($config['system']['developerspew'])) {
1296
		$mt = microtime();
1297
		echo "services_dyndns_configure() being called $mt\n";
1298
	}
1299

    
1300
	$dyndnscfg = $config['dyndnses']['dyndns'];
1301

    
1302
	if (is_array($dyndnscfg)) {
1303
		if ($g['booting'])
1304
			echo gettext("Starting DynDNS clients...");
1305

    
1306
		foreach ($dyndnscfg as $dyndns) {
1307
			if (!empty($int) && $int != $dyndns['interface'])
1308
				continue;
1309

    
1310
			services_dyndns_configure_client($dyndns);
1311

    
1312
			sleep(1);
1313
		}
1314

    
1315
		if ($g['booting'])
1316
			echo gettext("done.") . "\n";
1317
	}
1318

    
1319
	return 0;
1320
}
1321

    
1322
function services_dnsmasq_configure() {
1323
	global $config, $g;
1324
	$return = 0;
1325

    
1326
	if(isset($config['system']['developerspew'])) {
1327
		$mt = microtime();
1328
		echo "services_dnsmasq_configure() being called $mt\n";
1329
	}
1330

    
1331
	/* kill any running dnsmasq */
1332
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
1333
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1334

    
1335
	if (isset($config['dnsmasq']['enable'])) {
1336

    
1337
		if ($g['booting'])
1338
			echo gettext("Starting DNS forwarder...");
1339
		else
1340
			sleep(1);
1341

    
1342
		/* generate hosts file */
1343
		if(system_hosts_generate()!=0)
1344
			$return = 1;
1345

    
1346
		$args = "";
1347

    
1348
		if (isset($config['dnsmasq']['regdhcp'])) {
1349
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1350
		}
1351

    
1352
		/* Setup forwarded domains */
1353
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1354
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1355
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1356
			}
1357
		}
1358

    
1359
		/* Allow DNS Rebind for forwarded domains */
1360
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1361
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1362
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1363
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1364
				}
1365
			}
1366
		}
1367

    
1368
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1369
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1370

    
1371
		if ($config['dnsmasq']['custom_options']) {
1372
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
1373
				$args .= " --$c";
1374
		}
1375

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

    
1379
		if ($g['booting'])
1380
			echo gettext("done.") . "\n";
1381
	}
1382

    
1383
	if (!$g['booting']) {
1384
		if(services_dhcpd_configure()!=0)
1385
			$return = 1;
1386
	}
1387

    
1388
	return $return;
1389
}
1390

    
1391
function services_unbound_configure() {
1392
	global $config, $g;
1393
	$return = 0;
1394

    
1395
	if(isset($config['system']['developerspew'])) {
1396
		$mt = microtime();
1397
		echo "services_unbound_configure() being called $mt\n";
1398
	}
1399

    
1400
	/* kill any running unbound */
1401
	sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1402

    
1403
	if (isset($config['unbound']['enable'])) {
1404

    
1405
		if ($g['booting'])
1406
			echo "Starting Unbound DNS...";
1407
		else
1408
			sleep(1);
1409

    
1410
		/* generate Unbound config file */
1411
		if(unbound_generate_config()!=0) {
1412
			log_error("Problem generating Unbound configuration.");
1413
			$return = 1;
1414
		}
1415

    
1416
		/* run Unbound */
1417
		mwexec("/usr/local/sbin/unbound");
1418

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

    
1423
	return $return;
1424
}
1425

    
1426
function services_snmpd_configure() {
1427
	global $config, $g;
1428
	if(isset($config['system']['developerspew'])) {
1429
		$mt = microtime();
1430
		echo "services_snmpd_configure() being called $mt\n";
1431
	}
1432

    
1433
	/* kill any running snmpd */
1434
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1435
	sleep(2);
1436
	if(is_process_running("bsnmpd"))
1437
		mwexec("/usr/bin/killall bsnmpd", true);
1438

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

    
1441
		if ($g['booting'])
1442
			echo gettext("Starting SNMP daemon... ");
1443

    
1444
		/* generate snmpd.conf */
1445
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1446
		if (!$fd) {
1447
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1448
			return 1;
1449
		}
1450

    
1451

    
1452
		$snmpdconf = <<<EOD
1453
location := "{$config['snmpd']['syslocation']}"
1454
contact := "{$config['snmpd']['syscontact']}"
1455
read := "{$config['snmpd']['rocommunity']}"
1456

    
1457
EOD;
1458

    
1459
/* No docs on what write strings do there for disable for now.
1460
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1461
		    $snmpdconf .= <<<EOD
1462
# write string
1463
write := "{$config['snmpd']['rwcommunity']}"
1464

    
1465
EOD;
1466
		}
1467
*/
1468

    
1469

    
1470
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1471
		    $snmpdconf .= <<<EOD
1472
# SNMP Trap support.
1473
traphost := {$config['snmpd']['trapserver']}
1474
trapport := {$config['snmpd']['trapserverport']}
1475
trap := "{$config['snmpd']['trapstring']}"
1476

    
1477

    
1478
EOD;
1479
		}
1480

    
1481

    
1482
		$snmpdconf .= <<<EOD
1483
system := 1     # pfSense
1484
%snmpd
1485
begemotSnmpdDebugDumpPdus       = 2
1486
begemotSnmpdDebugSyslogPri      = 7
1487
begemotSnmpdCommunityString.0.1 = $(read)
1488

    
1489
EOD;
1490

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

    
1496
EOD;
1497
		}
1498
*/
1499

    
1500

    
1501
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1502
		    $snmpdconf .= <<<EOD
1503
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1504
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1505
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1506

    
1507
EOD;
1508
		}
1509

    
1510

    
1511
		$snmpdconf .= <<<EOD
1512
begemotSnmpdCommunityDisable    = 1
1513

    
1514
EOD;
1515

    
1516
		if (isset($config['snmpd']['bindlan'])) {
1517
			$config['snmpd']['bindip'] = 'lan';
1518
			unset($config['snmpd']['bindlan']);
1519
		}
1520
		$bind_to_ip = "0.0.0.0";
1521
		if(isset($config['snmpd']['bindip'])) {
1522
			if (is_ipaddr($config['snmpd']['bindip'])) {
1523
				$bind_to_ip = $config['snmpd']['bindip'];
1524
			} else {
1525
				$if = get_real_interface($config['snmpd']['bindip']);
1526
				if (does_interface_exist($if))
1527
					$bind_to_ip = find_interface_ip($if);
1528
			}
1529
		}
1530

    
1531
		if(is_port( $config['snmpd']['pollport'] )) {
1532
		    $snmpdconf .= <<<EOD
1533
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1534

    
1535
EOD;
1536

    
1537
		}
1538

    
1539
		$snmpdconf .= <<<EOD
1540
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1541
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1542

    
1543
# These are bsnmp macros not php vars.
1544
sysContact      = $(contact)
1545
sysLocation     = $(location)
1546
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1547

    
1548
snmpEnableAuthenTraps = 2
1549

    
1550
EOD;
1551

    
1552
		if (is_array( $config['snmpd']['modules'] )) {
1553
		    if(isset($config['snmpd']['modules']['mibii'])) {
1554
			$snmpdconf .= <<<EOD
1555
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1556

    
1557
EOD;
1558
		    }
1559

    
1560
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1561
			$snmpdconf .= <<<EOD
1562
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1563
%netgraph
1564
begemotNgControlNodeName = "snmpd"
1565

    
1566
EOD;
1567
		    }
1568

    
1569
		    if(isset($config['snmpd']['modules']['pf'])) {
1570
			$snmpdconf .= <<<EOD
1571
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1572

    
1573
EOD;
1574
		    }
1575

    
1576
		    if(isset($config['snmpd']['modules']['hostres'])) {
1577
			$snmpdconf .= <<<EOD
1578
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1579

    
1580
EOD;
1581
		    }
1582
		    if(isset($config['snmpd']['modules']['bridge'])) {
1583
			$snmpdconf .= <<<EOD
1584
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1585
# config must end with blank line
1586

    
1587

    
1588
EOD;
1589
		    }
1590
		}
1591

    
1592
		fwrite($fd, $snmpdconf);
1593
		fclose($fd);
1594

    
1595
		if (isset($config['snmpd']['bindlan'])) {
1596
			$bindlan = "";
1597
		}
1598

    
1599
		/* run bsnmpd */
1600
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1601
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1602

    
1603
		if ($g['booting'])
1604
			echo gettext("done.") . "\n";
1605
	}
1606

    
1607
	return 0;
1608
}
1609

    
1610
function services_dnsupdate_process($int = "") {
1611
	global $config, $g;
1612
	if(isset($config['system']['developerspew'])) {
1613
		$mt = microtime();
1614
		echo "services_dnsupdate_process() being called $mt\n";
1615
	}
1616

    
1617
	/* Dynamic DNS updating active? */
1618
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1619
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1620
			if (!isset($dnsupdate['enable']))
1621
				continue;
1622
			if (!empty($int) && $int != $dnsupdate['interface'])
1623
				continue;
1624

    
1625
			/* determine interface name */
1626
			$if = get_real_interface($dnsupdate['interface']);
1627
			$wanip = get_interface_ip($dnsupdate['interface']);
1628
			if ($wanip) {
1629

    
1630
				$keyname = $dnsupdate['keyname'];
1631
				/* trailing dot */
1632
				if (substr($keyname, -1) != ".")
1633
					$keyname .= ".";
1634

    
1635
				$hostname = $dnsupdate['host'];
1636
				/* trailing dot */
1637
				if (substr($hostname, -1) != ".")
1638
					$hostname .= ".";
1639

    
1640
				/* write private key file
1641
				   this is dumb - public and private keys are the same for HMAC-MD5,
1642
				   but nsupdate insists on having both */
1643
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1644
				$privkey = <<<EOD
1645
Private-key-format: v1.2
1646
Algorithm: 157 (HMAC)
1647
Key: {$dnsupdate['keydata']}
1648

    
1649
EOD;
1650
				fwrite($fd, $privkey);
1651
				fclose($fd);
1652

    
1653
				/* write public key file */
1654
				if ($dnsupdate['keytype'] == "zone") {
1655
					$flags = 257;
1656
					$proto = 3;
1657
				} else if ($dnsupdate['keytype'] == "host") {
1658
					$flags = 513;
1659
					$proto = 3;
1660
				} else if ($dnsupdate['keytype'] == "user") {
1661
					$flags = 0;
1662
					$proto = 2;
1663
				}
1664

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

    
1669
				/* generate update instructions */
1670
				$upinst = "";
1671
				if (!empty($dnsupdate['server']))
1672
					$upinst .= "server {$dnsupdate['server']}\n";
1673
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1674
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1675
				$upinst .= "\n";	/* mind that trailing newline! */
1676

    
1677
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1678
				fwrite($fd, $upinst);
1679
				fclose($fd);
1680

    
1681
				/* invoke nsupdate */
1682
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1683
				if (isset($dnsupdate['usetcp']))
1684
					$cmd .= " -v";
1685
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1686

    
1687
				mwexec_bg($cmd);
1688
			}
1689
		}
1690
	}
1691

    
1692
	return 0;
1693
}
1694

    
1695
function setup_wireless_olsr() {
1696
	global $config, $g;
1697
	if ($g['platform'] == 'jail' || !$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1698
		return;
1699
	if(isset($config['system']['developerspew'])) {
1700
		$mt = microtime();
1701
		echo "setup_wireless_olsr($interface) being called $mt\n";
1702
	}
1703
	conf_mount_rw();
1704
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1705
		$olsr_enable = $olsrd['enable'];
1706
		if($olsr_enable <> "on") {
1707
			if (is_process_running("olsrd"))
1708
				mwexec("/usr/bin/killall olsrd", true);
1709
			return;
1710
		}
1711
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1712

    
1713
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1714
			$enableannounce .= "\nHna4\n";
1715
			$enableannounce .= "{\n";
1716
		if($olsrd['announcedynamicroute'])
1717
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1718
		if($olsrd['enableannounce'] == "on")
1719
			$enableannounce .= "0.0.0.0 0.0.0.0";
1720
			$enableannounce .= "\n}\n";
1721
		} else {
1722
			$enableannounce = "";
1723
		}
1724

    
1725
		$olsr .= <<<EODA
1726
#
1727
# olsr.org OLSR daemon config file
1728
#
1729
# Lines starting with a # are discarded
1730
#
1731
# This file was generated by setup_wireless_olsr() in services.inc
1732
#
1733

    
1734
# This file is an example of a typical
1735
# configuration for a mostly static
1736
# network(regarding mobility) using
1737
# the LQ extention
1738

    
1739
# Debug level(0-9)
1740
# If set to 0 the daemon runs in the background
1741

    
1742
DebugLevel	2
1743

    
1744
# IP version to use (4 or 6)
1745

    
1746
IpVersion	4
1747

    
1748
# Clear the screen each time the internal state changes
1749

    
1750
ClearScreen     yes
1751

    
1752
{$enableannounce}
1753

    
1754
# Should olsrd keep on running even if there are
1755
# no interfaces available? This is a good idea
1756
# for a PCMCIA/USB hotswap environment.
1757
# "yes" OR "no"
1758

    
1759
AllowNoInt	yes
1760

    
1761
# TOS(type of service) value for
1762
# the IP header of control traffic.
1763
# If not set it will default to 16
1764

    
1765
#TosValue	16
1766

    
1767
# The fixed willingness to use(0-7)
1768
# If not set willingness will be calculated
1769
# dynamically based on battery/power status
1770
# if such information is available
1771

    
1772
#Willingness    	4
1773

    
1774
# Allow processes like the GUI front-end
1775
# to connect to the daemon.
1776

    
1777
IpcConnect
1778
{
1779
     # Determines how many simultaneously
1780
     # IPC connections that will be allowed
1781
     # Setting this to 0 disables IPC
1782

    
1783
     MaxConnections  0
1784

    
1785
     # By default only 127.0.0.1 is allowed
1786
     # to connect. Here allowed hosts can
1787
     # be added
1788

    
1789
     Host            127.0.0.1
1790
     #Host            10.0.0.5
1791

    
1792
     # You can also specify entire net-ranges
1793
     # that are allowed to connect. Multiple
1794
     # entries are allowed
1795

    
1796
     #Net             192.168.1.0 255.255.255.0
1797
}
1798

    
1799
# Wether to use hysteresis or not
1800
# Hysteresis adds more robustness to the
1801
# link sensing but delays neighbor registration.
1802
# Used by default. 'yes' or 'no'
1803

    
1804
UseHysteresis	no
1805

    
1806
# Hysteresis parameters
1807
# Do not alter these unless you know
1808
# what you are doing!
1809
# Set to auto by default. Allowed
1810
# values are floating point values
1811
# in the interval 0,1
1812
# THR_LOW must always be lower than
1813
# THR_HIGH.
1814

    
1815
#HystScaling	0.50
1816
#HystThrHigh	0.80
1817
#HystThrLow	0.30
1818

    
1819

    
1820
# Link quality level
1821
# 0 = do not use link quality
1822
# 1 = use link quality for MPR selection
1823
# 2 = use link quality for MPR selection and routing
1824
# Defaults to 0
1825

    
1826
LinkQualityLevel	{$olsrd['enablelqe']}
1827

    
1828
# Link quality window size
1829
# Defaults to 10
1830

    
1831
LinkQualityWinSize	10
1832

    
1833
# Polling rate in seconds(float).
1834
# Default value 0.05 sec
1835

    
1836
Pollrate	0.05
1837

    
1838

    
1839
# TC redundancy
1840
# Specifies how much neighbor info should
1841
# be sent in TC messages
1842
# Possible values are:
1843
# 0 - only send MPR selectors
1844
# 1 - send MPR selectors and MPRs
1845
# 2 - send all neighbors
1846
#
1847
# defaults to 0
1848

    
1849
TcRedundancy	2
1850

    
1851
#
1852
# MPR coverage
1853
# Specifies how many MPRs a node should
1854
# try select to reach every 2 hop neighbor
1855
#
1856
# Can be set to any integer >0
1857
#
1858
# defaults to 1
1859

    
1860
MprCoverage	3
1861

    
1862
# Example plugin entry with parameters:
1863

    
1864
EODA;
1865

    
1866
if($olsrd['enablehttpinfo'] == "on") {
1867
	$olsr .= <<<EODB
1868

    
1869
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1870
{
1871
    PlParam     "port"   "{$olsrd['port']}"
1872
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1873
}
1874

    
1875
EODB;
1876

    
1877
}
1878

    
1879
if($olsrd['enabledsecure'] == "on") {
1880
	$olsr .= <<<EODC
1881

    
1882
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1883
{
1884
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1885
}
1886

    
1887
EODC;
1888

    
1889
}
1890

    
1891
if($olsrd['enabledyngw'] == "on") {
1892

    
1893
	/* unset default route, olsr auto negotiates */
1894
	mwexec("/sbin/route delete default");
1895

    
1896
	$olsr .= <<<EODE
1897

    
1898
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1899
{
1900
    # how often to look for a inet gw, in seconds
1901
    # defaults to 5 secs, if commented out
1902
    PlParam     "Interval"   "{$olsrd['polling']}"
1903

    
1904
    # if one or more IPv4 addresses are given, do a ping on these in
1905
    # descending order to validate that there is not only an entry in
1906
    # routing table, but also a real internet connection. If any of
1907
    # these addresses could be pinged successfully, the test was
1908
    # succesful, i.e. if the ping on the 1st address was successful,the
1909
    # 2nd won't be pinged
1910
    PlParam     "Ping"       "{$olsrd['ping']}"
1911
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1912
}
1913

    
1914
EODE;
1915

    
1916
}
1917

    
1918
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1919
	$interfaces = explode(',', $conf['iface_array']);
1920
	foreach($interfaces as $interface) {
1921
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1922
$olsr .= <<<EODAD
1923
Interface "{$realinterface}"
1924
{
1925

    
1926
    # Hello interval in seconds(float)
1927
    HelloInterval    2.0
1928

    
1929
    # HELLO validity time
1930
    HelloValidityTime	20.0
1931

    
1932
    # TC interval in seconds(float)
1933
    TcInterval        5.0
1934

    
1935
    # TC validity time
1936
    TcValidityTime	30.0
1937

    
1938
    # MID interval in seconds(float)
1939
    MidInterval	5.0
1940

    
1941
    # MID validity time
1942
    MidValidityTime	30.0
1943

    
1944
    # HNA interval in seconds(float)
1945
    HnaInterval	5.0
1946

    
1947
    # HNA validity time
1948
    HnaValidityTime 	30.0
1949

    
1950
    # When multiple links exist between hosts
1951
    # the weight of interface is used to determine
1952
    # the link to use. Normally the weight is
1953
    # automatically calculated by olsrd based
1954
    # on the characteristics of the interface,
1955
    # but here you can specify a fixed value.
1956
    # Olsrd will choose links with the lowest value.
1957

    
1958
    # Weight 0
1959

    
1960

    
1961
}
1962

    
1963
EODAD;
1964

    
1965
	}
1966
	break;
1967
}
1968
		fwrite($fd, $olsr);
1969
		fclose($fd);
1970
	}
1971

    
1972
	if (is_process_running("olsrd"))
1973
		mwexec("/usr/bin/killall olsrd", true);
1974

    
1975
	sleep(2);
1976

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

    
1979
	conf_mount_ro();
1980
}
1981

    
1982
/* configure cron service */
1983
function configure_cron() {
1984
	global $g, $config;
1985

    
1986
	conf_mount_rw();
1987
	/* preserve existing crontab entries */
1988
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1989

    
1990
	for ($i = 0; $i < count($crontab_contents); $i++) {
1991
		$cron_item =& $crontab_contents[$i];
1992
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
1993
			array_splice($crontab_contents, $i - 1);
1994
			break;
1995
		}
1996
	}
1997
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
1998

    
1999

    
2000
	if (is_array($config['cron']['item'])) {
2001
		$crontab_contents .= "#\n";
2002
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2003
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
2004
		$crontab_contents .= "#\n";
2005

    
2006
		foreach ($config['cron']['item'] as $item) {
2007
			$crontab_contents .= "\n{$item['minute']}\t";
2008
			$crontab_contents .= "{$item['hour']}\t";
2009
			$crontab_contents .= "{$item['mday']}\t";
2010
			$crontab_contents .= "{$item['month']}\t";
2011
			$crontab_contents .= "{$item['wday']}\t";
2012
			$crontab_contents .= "{$item['who']}\t";
2013
			$crontab_contents .= "{$item['command']}";
2014
		}
2015

    
2016
		$crontab_contents .= "\n#\n";
2017
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2018
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2019
		$crontab_contents .= "#\n\n";
2020
	}
2021

    
2022
	/* please maintain the newline at the end of file */
2023
	file_put_contents("/etc/crontab", $crontab_contents);
2024

    
2025
	/* do a HUP kill to force sync changes */
2026
	exec('/bin/pkill -HUP cron');
2027

    
2028
	conf_mount_ro();
2029
}
2030

    
2031
function upnp_action ($action) {
2032
	global $g, $config;
2033
	switch($action) {
2034
		case "start":
2035
			if (file_exists('/var/etc/miniupnpd.conf')) {
2036
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
2037
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
2038
			}
2039
			break;
2040
		case "stop":
2041
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
2042
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
2043
				mwexec('killall miniupnpd 2>/dev/null', true);
2044
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
2045
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
2046
			break;
2047
		case "restart":
2048
			upnp_action('stop');
2049
			upnp_action('start');
2050
			break;
2051
	}
2052
}
2053

    
2054
function upnp_start() {
2055
	global $config;
2056

    
2057
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2058
		return;
2059

    
2060
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2061
		echo gettext("Starting UPnP service... ");
2062
		require_once('/usr/local/pkg/miniupnpd.inc');
2063
		sync_package_miniupnpd();
2064
		echo "done.\n";
2065
	}
2066
}
2067

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

    
2071
	$is_installed = false;
2072

    
2073
	if(!$config['cron']['item'])
2074
		return;
2075

    
2076
	$x=0;
2077
	foreach($config['cron']['item'] as $item) {
2078
		if(strstr($item['command'], $command)) {
2079
			$is_installed = true;
2080
			break;
2081
		}
2082
		$x++;
2083
	}
2084

    
2085
	if($active) {
2086
		$cron_item = array();
2087
		$cron_item['minute'] = $minute;
2088
		$cron_item['hour'] = $hour;
2089
		$cron_item['mday'] = $monthday;
2090
		$cron_item['month'] = $month;
2091
		$cron_item['wday'] = $weekday;
2092
		$cron_item['who'] = $who;
2093
		$cron_item['command'] = $command;
2094
		if(!$is_installed) {
2095
			$config['cron']['item'][] = $cron_item;
2096
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
2097
		} else {
2098
			$config['cron']['item'][$x] = $cron_item;
2099
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
2100
		}
2101
	} else {
2102
		if(($is_installed == true) && ($x > 0)) {
2103
			unset($config['cron']['item'][$x]);
2104
			write_config(sprintf(gettext("Remvoed cron job for %s"), $command));
2105
		}
2106
	}
2107
	configure_cron();
2108
}
2109

    
2110
?>
(46-46/64)