Project

General

Profile

Download (77.8 KB) Statistics
| Branch: | Tag: | Revision:
1 17f6eafa Scott Ullrich
<?php
2 5b237745 Scott Ullrich
/*
3
	services.inc
4 5721595b Chris Buechler
	part of the pfSense project (https://www.pfsense.org)
5 a25183c5 Scott Ullrich
6 417fc5c4 Scott Ullrich
	originally part of m0n0wall (http://m0n0.ch/wall)
7 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8 d98a2e6a Jose Luis Duran
	Copyright (C) 2010	Ermal Luçi
9 5b237745 Scott Ullrich
	All rights reserved.
10 a25183c5 Scott Ullrich
11 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13 a25183c5 Scott Ullrich
14 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16 a25183c5 Scott Ullrich
17 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
18
	   notice, this list of conditions and the following disclaimer in the
19
	   documentation and/or other materials provided with the distribution.
20 a25183c5 Scott Ullrich
21 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
	POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33 523855b0 Scott Ullrich
/*
34 05c4bfa0 Ermal
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/bin/pgrep	/bin/sh	/usr/local/sbin/dhcpd	/usr/local/sbin/igmpproxy
35 1944af41 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig		/usr/local/sbin/dnsmasq
36 950c9a18 Warren Baker
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/miniupnpd	/usr/sbin/radvd
37 1944af41 Ermal
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/dhcleases6	/usr/sbin/bsnmpd
38 523855b0 Scott Ullrich
	pfSense_MODULE:	utils
39
*/
40
41 c5ecdc25 Jose Luis Duran
define('DYNDNS_PROVIDER_VALUES', 'citynetwork cloudflare custom custom-v6 dhs dnsexit dnsimple dnsmadeeasy dnsomatic dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns glesys googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker loopia namecheap noip noip-free ods opendns ovh-dynhost route53 selfhost zoneedit');
42
define('DYNDNS_PROVIDER_DESCRIPTIONS', 'City Network,CloudFlare,Custom,Custom (v6),DHS,DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,GleSYS,Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,SelfHost,ZoneEdit');
43 0e3aeb6b Phil Davis
44 3aa55bbe Phil Davis
/* implement ipv6 route advertising daemon */
45 92977616 Ermal
function services_radvd_configure($blacklist = array()) {
46 d57293a4 Seth Mos
	global $config, $g;
47 61e047a5 Phil Davis
48
	if (isset($config['system']['developerspew'])) {
49 d57293a4 Seth Mos
		$mt = microtime();
50 3f9cc8e4 smos
		echo "services_radvd_configure() being called $mt\n";
51 d57293a4 Seth Mos
	}
52
53 61e047a5 Phil Davis
	if (!is_array($config['dhcpdv6'])) {
54 d57293a4 Seth Mos
		$config['dhcpdv6'] = array();
55 61e047a5 Phil Davis
	}
56 d57293a4 Seth Mos
57
	$Iflist = get_configured_interface_list();
58 e9ab2ddb smos
	$Iflist = array_merge($Iflist, get_configured_pppoe_server_interfaces());
59 abdd01f5 Ermal
	$carplist = get_configured_carp_interface_list();
60 d57293a4 Seth Mos
61 3f9cc8e4 smos
	$radvdconf = "# Automatically Generated, do not edit\n";
62 4a3ff493 Seth Mos
63 753bd64d Seth Mos
	/* Process all links which need the router advertise daemon */
64 3f9cc8e4 smos
	$radvdifs = array();
65 668e8961 smos
66 3f9cc8e4 smos
	/* handle manually configured DHCP6 server settings first */
67 dfac167c Ermal
	foreach ($config['dhcpdv6'] as $dhcpv6if => $dhcpv6ifconf) {
68 61e047a5 Phil Davis
		if (!is_array($config['interfaces'][$dhcpv6if])) {
69 dfac167c Ermal
			continue;
70 61e047a5 Phil Davis
		}
71
		if (!isset($config['interfaces'][$dhcpv6if]['enable'])) {
72 d7d2dc52 smos
			continue;
73 61e047a5 Phil Davis
		}
74 5078cd76 smos
75 92977616 Ermal
		/* Do not put in the config an interface which is down */
76 61e047a5 Phil Davis
		if (isset($blacklist[$dhcpv6if])) {
77 92977616 Ermal
			continue;
78 61e047a5 Phil Davis
		}
79
		if (!isset($dhcpv6ifconf['ramode'])) {
80 8ca73e85 smos
			$dhcpv6ifconf['ramode'] = $dhcpv6ifconf['mode'];
81 61e047a5 Phil Davis
		}
82 8ca73e85 smos
83 3f9cc8e4 smos
		/* are router advertisements enabled? */
84 61e047a5 Phil Davis
		if ($dhcpv6ifconf['ramode'] == "disabled") {
85 361bb4a9 smos
			continue;
86 61e047a5 Phil Davis
		}
87 d57293a4 Seth Mos
88 61e047a5 Phil Davis
		if (!isset($dhcpv6ifconf['rapriority'])) {
89 8ca73e85 smos
			$dhcpv6ifconf['rapriority'] = "medium";
90 61e047a5 Phil Davis
		}
91 8ca73e85 smos
92 25d1c6b2 smos
		/* always start with the real parent, we override with the carp if later */
93 83973bfb smos
		$carpif = false;
94 fe838158 smos
		/* check if we need to listen on a CARP interface */
95 dfac167c Ermal
		if (!empty($dhcpv6ifconf['rainterface'])) {
96 abdd01f5 Ermal
			if (!empty($carplist[$dhcpv6ifconf['rainterface']])) {
97
				$dhcpv6if = $dhcpv6ifconf['rainterface'];
98 83973bfb smos
				$carpif = true;
99 fe838158 smos
			}
100
		}
101 5078cd76 smos
102 2f74d9d8 Chris Buechler
		if (strstr($dhcpv6if, "_vip")) {
103 560d1b53 Renato Botelho
			// CARP IP, check if it's enabled and find parent
104 61e047a5 Phil Davis
			if (!get_carp_status() || get_carp_interface_status($dhcpv6if) != "MASTER") {
105 52b5a223 Renato Botelho
				continue;
106 61e047a5 Phil Davis
			}
107 2f74d9d8 Chris Buechler
			$ifparent = link_carp_interface_to_parent($dhcpv6if);
108
			$realif = convert_friendly_interface_to_real_interface_name($ifparent);
109
		} else {
110
			$realif = get_real_interface($dhcpv6if, "inet6");
111
		}
112 61e047a5 Phil Davis
113
		if (isset($radvdifs[$realif])) {
114 c18a10cc smos
			continue;
115 61e047a5 Phil Davis
		}
116 c18a10cc smos
117 2626cbd1 Ermal
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
118 61e047a5 Phil Davis
		if (!is_ipaddrv6($ifcfgipv6)) {
119 5078cd76 smos
			continue;
120 61e047a5 Phil Davis
		}
121 5078cd76 smos
122 d57293a4 Seth Mos
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
123
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
124 60c05056 Ermal
		$radvdifs[$realif] = $realif;
125 d57293a4 Seth Mos
126 3f9cc8e4 smos
		$radvdconf .= "# Generated for DHCPv6 Server $dhcpv6if\n";
127
		$radvdconf .= "interface {$realif} {\n";
128 e03b6bbc Chris Buechler
		if (strstr($realif, "ovpn")) {
129
			$radvdconf .= "\tUnicastOnly on;\n";
130
		}
131 3f9cc8e4 smos
		$radvdconf .= "\tAdvSendAdvert on;\n";
132 8859c0a6 smos
		$radvdconf .= "\tMinRtrAdvInterval 5;\n";
133
		$radvdconf .= "\tMaxRtrAdvInterval 20;\n";
134 a6bc492f Ermal
		$mtu = get_interface_mtu($realif);
135 61e047a5 Phil Davis
		if (is_numeric($mtu)) {
136 a6bc492f Ermal
			$radvdconf .= "\tAdvLinkMTU {$mtu};\n";
137 61e047a5 Phil Davis
		} else {
138 a6bc492f Ermal
			$radvdconf .= "\tAdvLinkMTU 1280;\n";
139 61e047a5 Phil Davis
		}
140 3f9cc8e4 smos
		// $radvdconf .= "\tDeprecatePrefix on;\n";
141 61e047a5 Phil Davis
		switch ($dhcpv6ifconf['rapriority']) {
142 fe838158 smos
			case "low":
143
				$radvdconf .= "\tAdvDefaultPreference low;\n";
144
				break;
145
			case "high":
146
				$radvdconf .= "\tAdvDefaultPreference high;\n";
147 838a1ecb smos
				break;
148
			default:
149
				$radvdconf .= "\tAdvDefaultPreference medium;\n";
150
				break;
151 fe838158 smos
		}
152 61e047a5 Phil Davis
		switch ($dhcpv6ifconf['ramode']) {
153 656f1763 Seth Mos
			case "managed":
154 3f9cc8e4 smos
			case "assist":
155 8c78e692 plinss
				$radvdconf .= "\tAdvManagedFlag on;\n";
156 3f9cc8e4 smos
				$radvdconf .= "\tAdvOtherConfigFlag on;\n";
157
				break;
158 bd7ce993 aqueeb
			case "stateless_dhcp":
159
				$radvdconf .= "\tAdvManagedFlag off;\n";
160
				$radvdconf .= "\tAdvOtherConfigFlag on;\n";
161
				break;
162 3f9cc8e4 smos
		}
163
		$radvdconf .= "\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
164 61e047a5 Phil Davis
		if ($carpif == true) {
165 83973bfb smos
			$radvdconf .= "\t\tDeprecatePrefix off;\n";
166 a99b2b08 smos
		} else {
167 83973bfb smos
			$radvdconf .= "\t\tDeprecatePrefix on;\n";
168 a99b2b08 smos
		}
169 61e047a5 Phil Davis
		switch ($dhcpv6ifconf['ramode']) {
170 3f9cc8e4 smos
			case "managed":
171
				$radvdconf .= "\t\tAdvOnLink on;\n";
172
				$radvdconf .= "\t\tAdvAutonomous off;\n";
173
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
174 826ac52c smos
				break;
175
			case "router":
176 3f9cc8e4 smos
				$radvdconf .= "\t\tAdvOnLink off;\n";
177
				$radvdconf .= "\t\tAdvAutonomous off;\n";
178
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
179 656f1763 Seth Mos
				break;
180 bd7ce993 aqueeb
			case "stateless_dhcp":
181 656f1763 Seth Mos
			case "assist":
182 3f9cc8e4 smos
				$radvdconf .= "\t\tAdvOnLink on;\n";
183
				$radvdconf .= "\t\tAdvAutonomous on;\n";
184
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
185 107e8acc Ovidiu Predescu
				break;
186 3f9cc8e4 smos
			case "unmanaged":
187
				$radvdconf .= "\t\tAdvOnLink on;\n";
188
				$radvdconf .= "\t\tAdvAutonomous on;\n";
189
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
190 61e047a5 Phil Davis
				break;
191 656f1763 Seth Mos
		}
192 3f9cc8e4 smos
		$radvdconf .= "\t};\n";
193
194 686e53c0 Chris Buechler
		if (is_array($dhcpv6ifconf['subnets']['item'])) {
195
			foreach ($dhcpv6ifconf['subnets']['item'] as $subnet) {
196
				if (is_subnetv6($subnet)) {
197
					$radvdconf .= "\tprefix {$subnet} {\n";
198 cf3904bd Phil Davis
					if ($carpif == true) {
199 686e53c0 Chris Buechler
						$radvdconf .= "\t\tDeprecatePrefix off;\n";
200
					} else {
201
						$radvdconf .= "\t\tDeprecatePrefix on;\n";
202
					}
203 cf3904bd Phil Davis
					switch ($dhcpv6ifconf['ramode']) {
204 686e53c0 Chris Buechler
						case "managed":
205
							$radvdconf .= "\t\tAdvOnLink on;\n";
206
							$radvdconf .= "\t\tAdvAutonomous off;\n";
207
							$radvdconf .= "\t\tAdvRouterAddr on;\n";
208
							break;
209
						case "router":
210
							$radvdconf .= "\t\tAdvOnLink off;\n";
211
							$radvdconf .= "\t\tAdvAutonomous off;\n";
212
							$radvdconf .= "\t\tAdvRouterAddr on;\n";
213
							break;
214
						case "assist":
215
							$radvdconf .= "\t\tAdvOnLink on;\n";
216
							$radvdconf .= "\t\tAdvAutonomous on;\n";
217
							$radvdconf .= "\t\tAdvRouterAddr on;\n";
218
							break;
219
						case "unmanaged":
220
							$radvdconf .= "\t\tAdvOnLink on;\n";
221
							$radvdconf .= "\t\tAdvAutonomous on;\n";
222
							$radvdconf .= "\t\tAdvRouterAddr on;\n";
223 086cf944 Phil Davis
							break;
224 686e53c0 Chris Buechler
					}
225
					$radvdconf .= "\t};\n";
226
				}
227
			}
228
		}
229 61e047a5 Phil Davis
		if ($carpif === true) {
230 dc131dfe smos
			$radvdconf .= "\troute ::/0 {\n";
231 8859c0a6 smos
			$radvdconf .= "\t\tRemoveRoute off;\n";
232
			$radvdconf .= "\t};\n";
233
		} else {
234 dc131dfe smos
			$radvdconf .= "\troute ::/0 {\n";
235
			$radvdconf .= "\t\tRemoveRoute on;\n";
236 8859c0a6 smos
			$radvdconf .= "\t};\n";
237
		}
238
239 f535d5a0 Seth Mos
		/* add DNS servers */
240 3aa114d5 Seth Mos
		$dnslist = array();
241 3d73a44d Renato Botelho
		if (isset($dhcpv6ifconf['rasamednsasdhcp6']) && is_array($dhcpv6ifconf['dnsserver']) && !empty($dhcpv6ifconf['dnsserver'])) {
242 61e047a5 Phil Davis
			foreach ($dhcpv6ifconf['dnsserver'] as $server) {
243
				if (is_ipaddrv6($server)) {
244 3d73a44d Renato Botelho
					$dnslist[] = $server;
245 61e047a5 Phil Davis
				}
246
			}
247 3d73a44d Renato Botelho
		} elseif (!isset($dhcpv6ifconf['rasamednsasdhcp6']) && isset($dhcpv6ifconf['radnsserver']) && is_array($dhcpv6ifconf['radnsserver'])) {
248 61e047a5 Phil Davis
			foreach ($dhcpv6ifconf['radnsserver'] as $server) {
249
				if (is_ipaddrv6($server)) {
250 3aa114d5 Seth Mos
					$dnslist[] = $server;
251 61e047a5 Phil Davis
				}
252
			}
253 f4620b36 Chris Buechler
		} elseif (isset($config['dnsmasq']['enable']) || isset($config['unbound']['enable'])) {
254 9a933304 smos
			$dnslist[] = get_interface_ipv6($realif);
255 abdd01f5 Ermal
		} elseif (is_array($config['system']['dnsserver']) && !empty($config['system']['dnsserver'])) {
256 61e047a5 Phil Davis
			foreach ($config['system']['dnsserver'] as $server) {
257
				if (is_ipaddrv6($server)) {
258 3aa114d5 Seth Mos
					$dnslist[] = $server;
259 61e047a5 Phil Davis
				}
260 3aa114d5 Seth Mos
			}
261
		}
262 abdd01f5 Ermal
		if (count($dnslist) > 0) {
263 3f9cc8e4 smos
			$dnsstring = implode(" ", $dnslist);
264 61e047a5 Phil Davis
			if ($dnsstring <> "") {
265 6c582308 smos
				$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
266 61e047a5 Phil Davis
			}
267 f535d5a0 Seth Mos
		}
268 abdd01f5 Ermal
		if (!empty($dhcpv6ifconf['domain'])) {
269 6c582308 smos
			$radvdconf .= "\tDNSSL {$dhcpv6ifconf['domain']} { };\n";
270 abdd01f5 Ermal
		} elseif (!empty($config['system']['domain'])) {
271 6c582308 smos
			$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
272 f535d5a0 Seth Mos
		}
273 3f9cc8e4 smos
		$radvdconf .= "};\n";
274 ed395640 Seth Mos
	}
275
276 3f9cc8e4 smos
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
277 ed395640 Seth Mos
	foreach ($Iflist as $if => $ifdescr) {
278 61e047a5 Phil Davis
		if (!isset($config['interfaces'][$if]['track6-interface'])) {
279 ed395640 Seth Mos
			continue;
280 61e047a5 Phil Davis
		}
281
		if (!isset($config['interfaces'][$if]['enable'])) {
282 d7d2dc52 smos
			continue;
283 61e047a5 Phil Davis
		}
284 92977616 Ermal
		/* Do not put in the config an interface which is down */
285 61e047a5 Phil Davis
		if (isset($blacklist[$if])) {
286 92977616 Ermal
			continue;
287 61e047a5 Phil Davis
		}
288 60c05056 Ermal
		$trackif = $config['interfaces'][$if]['track6-interface'];
289 61e047a5 Phil Davis
		if (empty($config['interfaces'][$trackif])) {
290 60c05056 Ermal
			continue;
291 61e047a5 Phil Davis
		}
292 60c05056 Ermal
293 2f74d9d8 Chris Buechler
		if (strstr($if, "_vip")) {
294
			// CARP IP, find parent
295
			$ifparent = link_carp_interface_to_parent($if);
296
			$realif = convert_friendly_interface_to_real_interface_name($ifparent);
297
		} else {
298
			$realif = get_real_interface($if, "inet6");
299
		}
300 61e047a5 Phil Davis
301 3f9cc8e4 smos
		/* prevent duplicate entries, manual overrides */
302 61e047a5 Phil Davis
		if (isset($radvdifs[$realif])) {
303 7492f21d smos
			continue;
304 61e047a5 Phil Davis
		}
305 7492f21d smos
306 ed395640 Seth Mos
		$ifcfgipv6 = get_interface_ipv6($if);
307 61e047a5 Phil Davis
		if (!is_ipaddrv6($ifcfgipv6)) {
308 75aec77a Ermal
			$subnetv6 = "::";
309
			$ifcfgsnv6 = "64";
310
		} else {
311
			$ifcfgsnv6 = get_interface_subnetv6($if);
312
			$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
313
		}
314 60c05056 Ermal
		$radvdifs[$realif] = $realif;
315 c18a10cc smos
316 20a7cb15 smos
		$autotype = $config['interfaces'][$trackif]['ipaddrv6'];
317 61e047a5 Phil Davis
318
		if ($g['debug']) {
319 dfac167c Ermal
			log_error("configuring RA on {$if} for type {$autotype} radvd subnet {$subnetv6}/{$ifcfgsnv6}");
320 61e047a5 Phil Davis
		}
321 668e8961 smos
322 60c05056 Ermal
		$radvdconf .= "# Generated config for {$autotype} delegation from {$trackif} on {$if}\n";
323
		$radvdconf .= "interface {$realif} {\n";
324
		$radvdconf .= "\tAdvSendAdvert on;\n";
325
		$radvdconf .= "\tMinRtrAdvInterval 3;\n";
326
		$radvdconf .= "\tMaxRtrAdvInterval 10;\n";
327
		$mtu = get_interface_mtu($realif);
328 61e047a5 Phil Davis
		if (is_numeric($mtu)) {
329 60c05056 Ermal
			$radvdconf .= "\tAdvLinkMTU {$mtu};\n";
330 61e047a5 Phil Davis
		} else {
331 60c05056 Ermal
			$radvdconf .= "\tAdvLinkMTU 1280;\n";
332 61e047a5 Phil Davis
		}
333 60c05056 Ermal
		$radvdconf .= "\tAdvOtherConfigFlag on;\n";
334
		$radvdconf .= "\t\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
335
		$radvdconf .= "\t\tAdvOnLink on;\n";
336
		$radvdconf .= "\t\tAdvAutonomous on;\n";
337
		$radvdconf .= "\t\tAdvRouterAddr on;\n";
338
		$radvdconf .= "\t};\n";
339
340
		/* add DNS servers */
341 668e8961 smos
		$dnslist = array();
342 f4620b36 Chris Buechler
		if (isset($config['dnsmasq']['enable']) || isset($config['unbound']['enable'])) {
343 60c05056 Ermal
			$dnslist[] = $ifcfgipv6;
344
		} elseif (is_array($config['system']['dnsserver']) && !empty($config['system']['dnsserver'])) {
345 61e047a5 Phil Davis
			foreach ($config['system']['dnsserver'] as $server) {
346
				if (is_ipaddrv6($server)) {
347 60c05056 Ermal
					$dnslist[] = $server;
348 61e047a5 Phil Davis
				}
349 60c05056 Ermal
			}
350 668e8961 smos
		}
351 60c05056 Ermal
		if (count($dnslist) > 0) {
352
			$dnsstring = implode(" ", $dnslist);
353 61e047a5 Phil Davis
			if (!empty($dnsstring)) {
354 60c05056 Ermal
				$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
355 61e047a5 Phil Davis
			}
356 60c05056 Ermal
		}
357
		if (!empty($config['system']['domain'])) {
358
			$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
359
		}
360
		$radvdconf .= "};\n";
361 668e8961 smos
	}
362
363 928d4416 Ermal
	/* write radvd.conf */
364 abdd01f5 Ermal
	if (!@file_put_contents("{$g['varetc_path']}/radvd.conf", $radvdconf)) {
365
		log_error("Error: cannot open radvd.conf in services_radvd_configure().\n");
366 61e047a5 Phil Davis
		if (platform_booting()) {
367 abdd01f5 Ermal
			printf("Error: cannot open radvd.conf in services_radvd_configure().\n");
368 61e047a5 Phil Davis
		}
369 abdd01f5 Ermal
	}
370 928d4416 Ermal
	unset($radvdconf);
371 d57293a4 Seth Mos
372 abdd01f5 Ermal
	if (count($radvdifs) > 0) {
373 61e047a5 Phil Davis
		if (isvalidpid("{$g['varrun_path']}/radvd.pid")) {
374 abdd01f5 Ermal
			sigkillbypid("{$g['varrun_path']}/radvd.pid", "HUP");
375 61e047a5 Phil Davis
		} else {
376 abdd01f5 Ermal
			mwexec("/usr/local/sbin/radvd -p {$g['varrun_path']}/radvd.pid -C {$g['varetc_path']}/radvd.conf -m syslog");
377 61e047a5 Phil Davis
		}
378 6afeb202 smos
	} else {
379
		/* we need to shut down the radvd cleanly, it will send out the prefix
380
		 * information with a lifetime of 0 to notify clients of a (possible) new prefix */
381 abdd01f5 Ermal
		if (isvalidpid("{$g['varrun_path']}/radvd.pid")) {
382 6afeb202 smos
			log_error("Shutting down Router Advertisment daemon cleanly");
383 abdd01f5 Ermal
			killbypid("{$g['varrun_path']}/radvd.pid");
384 dfac167c Ermal
			@unlink("{$g['varrun_path']}/radvd.pid");
385 6afeb202 smos
		}
386 d57293a4 Seth Mos
	}
387
	return 0;
388
}
389
390 92977616 Ermal
function services_dhcpd_configure($family = "all", $blacklist = array()) {
391 f19d3b7a Scott Ullrich
	global $config, $g;
392 2fb056d8 Seth Mos
393
	/* configure DHCPD chroot once */
394 086cf944 Phil Davis
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh", "w");
395 d6c82882 Ermal
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}\n");
396
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
397
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
398
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
399
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
400
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
401
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
402
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
403
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/run\n");
404
	fwrite($fd, "/usr/sbin/chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
405 06886ae3 Ermal
	fwrite($fd, "/bin/cp -n /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
406
	fwrite($fd, "/bin/cp -n /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
407 60214e06 bcyrill
	fwrite($fd, "/bin/chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
408 d6c82882 Ermal
409 6c07db48 Phil Davis
	$status = `/sbin/mount | /usr/bin/grep -v grep | /usr/bin/grep "{$g['dhcpd_chroot_path']}/dev"`;
410 61e047a5 Phil Davis
	if (!trim($status)) {
411 d6c82882 Ermal
		fwrite($fd, "/sbin/mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
412 61e047a5 Phil Davis
	}
413 2fb056d8 Seth Mos
	fclose($fd);
414
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
415
416 61e047a5 Phil Davis
	if ($family == "all" || $family == "inet") {
417 3084ba6e Ermal
		services_dhcpdv4_configure();
418 61e047a5 Phil Davis
	}
419 3084ba6e Ermal
	if ($family == "all" || $family == "inet6") {
420 92977616 Ermal
		services_dhcpdv6_configure($blacklist);
421
		services_radvd_configure($blacklist);
422 3084ba6e Ermal
	}
423 2fb056d8 Seth Mos
}
424 1c903aa4 Ermal
425 2fb056d8 Seth Mos
function services_dhcpdv4_configure() {
426
	global $config, $g;
427 3df2dbfd jim-p
	$need_ddns_updates = false;
428
	$ddns_zones = array();
429 107e8acc Ovidiu Predescu
430 61e047a5 Phil Davis
	if ($g['services_dhcp_server_enable'] == false) {
431 e3a13b00 Scott Ullrich
		return;
432 61e047a5 Phil Davis
	}
433 e3a13b00 Scott Ullrich
434 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
435 acd910bf Scott Ullrich
		$mt = microtime();
436 2fb056d8 Seth Mos
		echo "services_dhcpdv4_configure($if) being called $mt\n";
437 acd910bf Scott Ullrich
	}
438 107e8acc Ovidiu Predescu
439 af25d415 Chris Buechler
	/* kill any running dhcpd */
440 61e047a5 Phil Davis
	if (isvalidpid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid")) {
441 ed395640 Seth Mos
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
442 61e047a5 Phil Davis
	}
443 a25183c5 Scott Ullrich
444 15be1722 Ermal Luçi
	/* DHCP enabled on any interfaces? */
445 61e047a5 Phil Davis
	if (!is_dhcp_server_enabled()) {
446 15be1722 Ermal Luçi
		return 0;
447 61e047a5 Phil Davis
	}
448 15be1722 Ermal Luçi
449 48ab0cd2 Scott Ullrich
	/* if OLSRD is enabled, allow WAN to house DHCP. */
450 61e047a5 Phil Davis
	if (!function_exists('is_package_installed')) {
451 86ce2df7 Renato Botelho
		require_once('pkg-utils.inc');
452 61e047a5 Phil Davis
	}
453
	if (is_package_installed('olsrd') && isset($config['installedpackages']['olsrd'])) {
454
		foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
455 86ce2df7 Renato Botelho
			if (isset($olsrd['enable']) && $olsrd['enable'] == "on") {
456
				$is_olsr_enabled = true;
457
				break;
458
			}
459 61e047a5 Phil Davis
		}
460
	}
461 48ab0cd2 Scott Ullrich
462 285ef132 Ermal LUÇI
	if (platform_booting()) {
463 e92e83d4 jim-p
		/* restore the leases, if we have them */
464
		if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
465
			$dhcprestore = "";
466
			$dhcpreturn = "";
467
			exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
468
			$dhcprestore = implode(" ", $dhcprestore);
469 61e047a5 Phil Davis
			if ($dhcpreturn <> 0) {
470 e92e83d4 jim-p
				log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n"));
471 381e43e0 jim-p
			}
472
		}
473 e92e83d4 jim-p
		/* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */
474
		if (($g['platform'] == "pfSense") && !isset($config['system']['use_mfs_tmpvar'])) {
475
			unlink_if_exists("{$g['cf_conf_path']}/dhcpleases.tgz");
476
		}
477 381e43e0 jim-p
	}
478
479 5b237745 Scott Ullrich
	$syscfg = $config['system'];
480 61e047a5 Phil Davis
	if (!is_array($config['dhcpd'])) {
481 a8a98fb4 Seth Mos
		$config['dhcpd'] = array();
482 61e047a5 Phil Davis
	}
483 d57293a4 Seth Mos
	$dhcpdcfg = $config['dhcpd'];
484 6f9b8073 Ermal Luçi
	$Iflist = get_configured_interface_list();
485 107e8acc Ovidiu Predescu
486 3ad6b569 Phil Davis
	/* Only consider DNS servers with IPv4 addresses for the IPv4 DHCP server. */
487
	$dns_arrv4 = array();
488 68169a55 jim-p
	if (is_array($syscfg['dnsserver'])) {
489 61e047a5 Phil Davis
		foreach ($syscfg['dnsserver'] as $dnsserver) {
490 68169a55 jim-p
			if (is_ipaddrv4($dnsserver)) {
491
				$dns_arrv4[] = $dnsserver;
492
			}
493 3ad6b569 Phil Davis
		}
494
	}
495
496 61e047a5 Phil Davis
	if (platform_booting()) {
497 f1a44a3a Carlos Eduardo Ramos
		echo gettext("Starting DHCP service...");
498 61e047a5 Phil Davis
	} else {
499 5b237745 Scott Ullrich
		sleep(1);
500 61e047a5 Phil Davis
	}
501 a25183c5 Scott Ullrich
502 518030b3 Scott Ullrich
	$custoptions = "";
503 107e8acc Ovidiu Predescu
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
504 61e047a5 Phil Davis
		if (is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
505
			foreach ($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
506
				if (!empty($item['type'])) {
507 678dfd0f Erik Fonnesbeck
					$itemtype = $item['type'];
508 61e047a5 Phil Davis
				} else {
509 678dfd0f Erik Fonnesbeck
					$itemtype = "text";
510 61e047a5 Phil Davis
				}
511 678dfd0f Erik Fonnesbeck
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
512 518030b3 Scott Ullrich
			}
513
		}
514
	}
515 4cab31d0 Scott Ullrich
516 5b237745 Scott Ullrich
	$dhcpdconf = <<<EOD
517 107e8acc Ovidiu Predescu
518 5b237745 Scott Ullrich
option domain-name "{$syscfg['domain']}";
519 6c23757b Martin Fuchs
option ldap-server code 95 = text;
520 9be23653 Martin Fuchs
option domain-search-list code 119 = text;
521 fdb116a9 Donald A. Cupp Jr
option arch code 93 = unsigned integer 16; # RFC4578
522 518030b3 Scott Ullrich
{$custoptions}
523 5b237745 Scott Ullrich
default-lease-time 7200;
524
max-lease-time 86400;
525
log-facility local7;
526 175fe82b Scott Ullrich
one-lease-per-client true;
527 436a0f50 Scott Ullrich
deny duplicates;
528 9c88328f Scott Ullrich
ping-check true;
529 87019fc4 Andres Petralli
update-conflict-detection false;
530 5b237745 Scott Ullrich
531
EOD;
532 a25183c5 Scott Ullrich
533 61e047a5 Phil Davis
	if (!isset($dhcpifconf['disableauthoritative'])) {
534 d8912c6b Chris Buechler
		$dhcpdconf .= "authoritative;\n";
535 61e047a5 Phil Davis
	}
536 d8912c6b Chris Buechler
537 61e047a5 Phil Davis
	if (isset($dhcpifconf['alwaysbroadcast'])) {
538 5252b98d Scott Ullrich
		$dhcpdconf .= "always-broadcast on\n";
539 61e047a5 Phil Davis
	}
540 5252b98d Scott Ullrich
541 5b237745 Scott Ullrich
	$dhcpdifs = array();
542 3f141c9d Phil Davis
	$enable_add_routers = false;
543 c08a5659 smos
	$gateways_arr = return_gateways_array();
544
	/* only add a routers line if the system has any IPv4 gateway at all */
545
	/* a static route has a gateway, manually overriding this field always works */
546 61e047a5 Phil Davis
	foreach ($gateways_arr as $gwitem) {
547
		if ($gwitem['ipprotocol'] == "inet") {
548 3f141c9d Phil Davis
			$enable_add_routers = true;
549 c08a5659 smos
			break;
550
		}
551
	}
552 c7f44ae0 Scott Ullrich
553 4494cf6a Chris Buechler
	/*    loop through and determine if we need to setup
554 8fa56d1f Scott Ullrich
	 *    failover peer "bleh" entries
555
	 */
556
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
557 53f32329 Scott Ullrich
558 61e047a5 Phil Davis
		if (!isset($config['interfaces'][$dhcpif]['enable'])) {
559 57006646 Renato Botelho
			continue;
560 61e047a5 Phil Davis
		}
561 57006646 Renato Botelho
562 09f11c71 jim-p
		interfaces_staticarp_configure($dhcpif);
563
564 61e047a5 Phil Davis
		if (!isset($dhcpifconf['enable'])) {
565 6f9b8073 Ermal Luçi
			continue;
566 61e047a5 Phil Davis
		}
567 6f9b8073 Ermal Luçi
568 61e047a5 Phil Davis
		if ($dhcpifconf['failover_peerip'] <> "") {
569 a01f8bfc Ermal
			$intip = get_interface_ip($dhcpif);
570 8fa56d1f Scott Ullrich
			/*
571
			 *    yep, failover peer is defined.
572
			 *    does it match up to a defined vip?
573
			 */
574 d2edbd8a Scott Ullrich
			$skew = 110;
575 61e047a5 Phil Davis
			if (is_array($config['virtualip']['vip'])) {
576 9d7ca11f Ermal
				foreach ($config['virtualip']['vip'] as $vipent) {
577 61e047a5 Phil Davis
					if ($vipent['interface'] == $dhcpif) {
578 a01f8bfc Ermal
						$carp_nw = gen_subnet($vipent['subnet'], $vipent['subnet_bits']);
579
						if (ip_in_subnet($dhcpifconf['failover_peerip'], "{$carp_nw}/{$vipent['subnet_bits']}")) {
580
							/* this is the interface! */
581 61e047a5 Phil Davis
							if (is_numeric($vipent['advskew']) && (intval($vipent['advskew']) < 20)) {
582 a01f8bfc Ermal
								$skew = 0;
583
								break;
584
							}
585
						}
586 6181b36f Scott Ullrich
					}
587 8fa56d1f Scott Ullrich
				}
588 25066204 Scott Ullrich
			} else {
589 959dc96b Chris Buechler
				log_error(gettext("Warning!  DHCP Failover setup and no CARP virtual IPs defined!"));
590 8fa56d1f Scott Ullrich
			}
591 61e047a5 Phil Davis
			if ($skew > 10) {
592 8fa56d1f Scott Ullrich
				$type = "secondary";
593 0e93097a Scott Ullrich
				$my_port = "520";
594
				$peer_port = "519";
595 8fa56d1f Scott Ullrich
			} else {
596 0e93097a Scott Ullrich
				$my_port = "519";
597
				$peer_port = "520";
598 8fa56d1f Scott Ullrich
				$type = "primary";
599 6c07db48 Phil Davis
				$dhcpdconf_pri = "split 128;\n";
600 1a0bb737 Scott Ullrich
				$dhcpdconf_pri .= "  mclt 600;\n";
601 8fa56d1f Scott Ullrich
			}
602 a01f8bfc Ermal
603
			if (is_ipaddrv4($intip)) {
604 61e047a5 Phil Davis
				$dhcpdconf .= <<<EOPP
605 d5e4f7c9 jim-p
failover peer "dhcp_{$dhcpif}" {
606 8fa56d1f Scott Ullrich
  {$type};
607
  address {$intip};
608 0e93097a Scott Ullrich
  port {$my_port};
609 8fa56d1f Scott Ullrich
  peer address {$dhcpifconf['failover_peerip']};
610 0e93097a Scott Ullrich
  peer port {$peer_port};
611 2cd5ce14 Scott Ullrich
  max-response-delay 10;
612 b865d178 Scott Ullrich
  max-unacked-updates 10;
613
  {$dhcpdconf_pri}
614 b259d1c6 Scott Ullrich
  load balance max seconds 3;
615 8fa56d1f Scott Ullrich
}
616 959dc96b Chris Buechler
\n
617 8fa56d1f Scott Ullrich
EOPP;
618 a01f8bfc Ermal
			}
619 8fa56d1f Scott Ullrich
		}
620
	}
621
622 5b237745 Scott Ullrich
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
623 a25183c5 Scott Ullrich
624 3df2dbfd jim-p
		$newzone = array();
625 5b237745 Scott Ullrich
		$ifcfg = $config['interfaces'][$dhcpif];
626 a25183c5 Scott Ullrich
627 61e047a5 Phil Davis
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif])) {
628 5b237745 Scott Ullrich
			continue;
629 61e047a5 Phil Davis
		}
630 a55e9c70 Ermal Lu?i
		$ifcfgip = get_interface_ip($dhcpif);
631
		$ifcfgsn = get_interface_subnet($dhcpif);
632
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
633
		$subnetmask = gen_subnet_mask($ifcfgsn);
634 a25183c5 Scott Ullrich
635 61e047a5 Phil Davis
		if (!is_ipaddr($subnet)) {
636 85e3f445 Ermal
			continue;
637 61e047a5 Phil Davis
		}
638 85e3f445 Ermal
639 61e047a5 Phil Davis
		if ($is_olsr_enabled == true) {
640
			if ($dhcpifconf['netmask']) {
641 9a537862 Scott Ullrich
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
642 61e047a5 Phil Davis
			}
643
		}
644 48ab0cd2 Scott Ullrich
645 cba980f6 jim-p
		$all_pools = array();
646
		$all_pools[] = $dhcpifconf;
647
		if (is_array($dhcpifconf['pool'])) {
648
			$all_pools = array_merge($all_pools, $dhcpifconf['pool']);
649
		}
650
651 5b237745 Scott Ullrich
		$dnscfg = "";
652 a25183c5 Scott Ullrich
653 5b237745 Scott Ullrich
		if ($dhcpifconf['domain']) {
654
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
655
		}
656 107e8acc Ovidiu Predescu
657 61e047a5 Phil Davis
		if ($dhcpifconf['domainsearchlist'] <> "") {
658 a3de8b9e Pierre POMES
			$dnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpifconf['domainsearchlist'])) . "\";\n";
659 84931046 jim-p
		}
660 9be23653 Martin Fuchs
661 4e9cd828 Seth Mos
		if (isset($dhcpifconf['ddnsupdate'])) {
662 3df2dbfd jim-p
			$need_ddns_updates = true;
663
			$newzone = array();
664 61e047a5 Phil Davis
			if ($dhcpifconf['ddnsdomain'] <> "") {
665 3df2dbfd jim-p
				$newzone['domain-name'] = $dhcpifconf['ddnsdomain'];
666 4e9cd828 Seth Mos
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
667 3df2dbfd jim-p
			} else {
668
				$newzone['domain-name'] = $config['system']['domain'];
669
			}
670
			$revsubnet = explode(".", $subnet);
671
			$revsubnet = array_reverse($revsubnet);
672
			foreach ($revsubnet as $octet) {
673 61e047a5 Phil Davis
				if ($octet != "0") {
674 3df2dbfd jim-p
					break;
675 61e047a5 Phil Davis
				}
676 3df2dbfd jim-p
				array_shift($revsubnet);
677 4e9cd828 Seth Mos
			}
678 3df2dbfd jim-p
			$newzone['ptr-domain'] = implode(".", $revsubnet) . ".in-addr.arpa";
679 4e9cd828 Seth Mos
		}
680
681 aff9d6ab Scott Ullrich
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
682 8ee01642 Scott Ullrich
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
683 61e047a5 Phil Davis
			if ($newzone['domain-name']) {
684 3df2dbfd jim-p
				$newzone['dns-servers'] = $dhcpifconf['dnsserver'];
685 61e047a5 Phil Davis
			}
686 aff9d6ab Scott Ullrich
		} else if (isset($config['dnsmasq']['enable'])) {
687 a55e9c70 Ermal Lu?i
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
688 61e047a5 Phil Davis
			if ($newzone['domain-name'] && is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
689 3df2dbfd jim-p
				$newzone['dns-servers'] = $syscfg['dnsserver'];
690 61e047a5 Phil Davis
			}
691 88a0937d Chris Buechler
		} else if (isset($config['unbound']['enable'])) {
692
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
693 3ad6b569 Phil Davis
		} else if (!empty($dns_arrv4)) {
694
			$dnscfg .= "	option domain-name-servers " . join(",", $dns_arrv4) . ";";
695 61e047a5 Phil Davis
			if ($newzone['domain-name']) {
696 3ad6b569 Phil Davis
				$newzone['dns-servers'] = $dns_arrv4;
697 61e047a5 Phil Davis
			}
698 aff9d6ab Scott Ullrich
		}
699
700 61e047a5 Phil Davis
		/* Create classes - These all contain comma separated lists. Join them into one
701 cba980f6 jim-p
		   big comma separated string then split them all up. */
702
		$all_mac_strings = array();
703
		if (is_array($dhcpifconf['pool'])) {
704 61e047a5 Phil Davis
			foreach ($all_pools as $poolconf) {
705 cba980f6 jim-p
				$all_mac_strings[] = $poolconf['mac_allow'];
706
				$all_mac_strings[] = $poolconf['mac_deny'];
707
			}
708
		}
709
		$all_mac_strings[] = $dhcpifconf['mac_allow'];
710
		$all_mac_strings[] = $dhcpifconf['mac_deny'];
711 7fd93993 Ermal LUÇI
		if (!empty($all_mac_strings)) {
712
			$all_mac_list = array_unique(explode(',', implode(',', $all_mac_strings)));
713
			foreach ($all_mac_list as $mac) {
714
				if (empty($mac)) {
715
					continue;
716
				}
717
				$dhcpdconf .= 'class "' . str_replace(':', '', $mac) . '" {' . "\n";
718
				// Skip the first octet of the MAC address - for media type, typically Ethernet ("01") and match the rest.
719
				$dhcpdconf .= '	match if substring (hardware, 1, ' . (substr_count($mac, ':') + 1) . ') = ' . $mac . ';' . "\n";
720
				$dhcpdconf .= '}' . "\n";
721 61e047a5 Phil Davis
			}
722 1f1a08c8 jim-p
		}
723
724 85e3f445 Ermal
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
725 c7f44ae0 Scott Ullrich
726 61e047a5 Phil Davis
		// Setup pool options
727
		foreach ($all_pools as $poolconf) {
728 cba980f6 jim-p
			$dhcpdconf .= "	pool {\n";
729
			/* is failover dns setup? */
730
			if (is_array($poolconf['dnsserver']) && $poolconf['dnsserver'][0] <> "") {
731
				$dhcpdconf .= "		option domain-name-servers {$poolconf['dnsserver'][0]}";
732 61e047a5 Phil Davis
				if ($poolconf['dnsserver'][1] <> "") {
733 cba980f6 jim-p
					$dhcpdconf .= ",{$poolconf['dnsserver'][1]}";
734 61e047a5 Phil Davis
				}
735
				if ($poolconf['dnsserver'][2] <> "") {
736 8cbb140a Phil Davis
					$dhcpdconf .= ",{$poolconf['dnsserver'][2]}";
737 61e047a5 Phil Davis
				}
738
				if ($poolconf['dnsserver'][3] <> "") {
739 8cbb140a Phil Davis
					$dhcpdconf .= ",{$poolconf['dnsserver'][3]}";
740 61e047a5 Phil Davis
				}
741 cba980f6 jim-p
				$dhcpdconf .= ";\n";
742
			}
743
744
			/* allow/deny MACs */
745
			$mac_allow_list = array_unique(explode(',', $poolconf['mac_allow']));
746
			foreach ($mac_allow_list as $mac) {
747 61e047a5 Phil Davis
				if (empty($mac)) {
748 cba980f6 jim-p
					continue;
749 61e047a5 Phil Davis
				}
750 cba980f6 jim-p
				$dhcpdconf .= "		allow members of \"" . str_replace(':', '', $mac) . "\";\n";
751
			}
752
			$mac_deny_list = array_unique(explode(',', $poolconf['mac_deny']));
753
			foreach ($mac_deny_list as $mac) {
754 61e047a5 Phil Davis
				if (empty($mac)) {
755 cba980f6 jim-p
					continue;
756 61e047a5 Phil Davis
				}
757 cba980f6 jim-p
				$dhcpdconf .= "		deny members of \"" . str_replace(':', '', $mac) . "\";\n";
758
			}
759
760 61e047a5 Phil Davis
			if ($poolconf['failover_peerip'] <> "") {
761 cba980f6 jim-p
				$dhcpdconf .= "		deny dynamic bootp clients;\n";
762 61e047a5 Phil Davis
			}
763 cba980f6 jim-p
764 61e047a5 Phil Davis
			if (isset($poolconf['denyunknown'])) {
765 cba980f6 jim-p
			   $dhcpdconf .= "		deny unknown-clients;\n";
766 61e047a5 Phil Davis
			}
767 cba980f6 jim-p
768 61e047a5 Phil Davis
			if ($poolconf['gateway'] && $poolconf['gateway'] != "none" && ($poolconf['gateway'] != $dhcpifconf['gateway'])) {
769 f9f6f7d4 jim-p
				$dhcpdconf .= "		option routers {$poolconf['gateway']};\n";
770 61e047a5 Phil Davis
			}
771 cba980f6 jim-p
772 61e047a5 Phil Davis
			if ($dhcpifconf['failover_peerip'] <> "") {
773 d5e4f7c9 jim-p
				$dhcpdconf .= "		failover peer \"dhcp_{$dhcpif}\";\n";
774 cba980f6 jim-p
			}
775
776
			$pdnscfg = "";
777
778
			if ($poolconf['domain'] && ($poolconf['domain'] != $dhcpifconf['domain'])) {
779
				$pdnscfg .= "		option domain-name \"{$poolconf['domain']}\";\n";
780
			}
781
782 61e047a5 Phil Davis
			if (!empty($poolconf['domainsearchlist']) && ($poolconf['domainsearchlist'] != $dhcpifconf['domainsearchlist'])) {
783 cba980f6 jim-p
				$pdnscfg .= "		option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $poolconf['domainsearchlist'])) . "\";\n";
784
			}
785
786 7309ff39 Renato Botelho
			if (isset($poolconf['ddnsupdate'])) {
787 61e047a5 Phil Davis
				if (($poolconf['ddnsdomain'] <> "") && ($poolconf['ddnsdomain'] != $dhcpifconf['ddnsdomain'])) {
788 cba980f6 jim-p
					$pdnscfg .= "		ddns-domainname \"{$poolconf['ddnsdomain']}\";\n";
789 61e047a5 Phil Davis
				}
790 cba980f6 jim-p
				$pdnscfg .= "		ddns-update-style interim;\n";
791
			}
792
793 fa7b825f Renato Botelho
			if (is_array($poolconf['dnsserver']) && ($poolconf['dnsserver'][0]) && ($poolconf['dnsserver'][0] != $dhcpifconf['dnsserver'][0])) {
794 cba980f6 jim-p
				$pdnscfg .= "		option domain-name-servers " . join(",", $poolconf['dnsserver']) . ";\n";
795
			}
796
			$dhcpdconf .= "{$pdnscfg}";
797 1f1a08c8 jim-p
798 cba980f6 jim-p
			// default-lease-time
799 61e047a5 Phil Davis
			if ($poolconf['defaultleasetime'] && ($poolconf['defaultleasetime'] != $dhcpifconf['defaultleasetime'])) {
800 cba980f6 jim-p
				$dhcpdconf .= "		default-lease-time {$poolconf['defaultleasetime']};\n";
801 61e047a5 Phil Davis
			}
802 cba980f6 jim-p
803
			// max-lease-time
804 61e047a5 Phil Davis
			if ($poolconf['maxleasetime'] && ($poolconf['maxleasetime'] != $dhcpifconf['maxleasetime'])) {
805 cba980f6 jim-p
				$dhcpdconf .= "		max-lease-time {$poolconf['maxleasetime']};\n";
806 61e047a5 Phil Davis
			}
807 cba980f6 jim-p
808
			// netbios-name*
809 fa7b825f Renato Botelho
			if (is_array($poolconf['winsserver']) && $poolconf['winsserver'][0] && ($poolconf['winsserver'][0] != $dhcpifconf['winsserver'][0])) {
810 cba980f6 jim-p
				$dhcpdconf .= "		option netbios-name-servers " . join(",", $poolconf['winsserver']) . ";\n";
811
				$dhcpdconf .= "		option netbios-node-type 8;\n";
812
			}
813 c7f44ae0 Scott Ullrich
814 cba980f6 jim-p
			// ntp-servers
815 61e047a5 Phil Davis
			if (is_array($poolconf['ntpserver']) && $poolconf['ntpserver'][0] && ($poolconf['ntpserver'][0] != $dhcpifconf['ntpserver'][0])) {
816 cba980f6 jim-p
				$dhcpdconf .= "		option ntp-servers " . join(",", $poolconf['ntpserver']) . ";\n";
817 61e047a5 Phil Davis
			}
818 cba980f6 jim-p
819
			// tftp-server-name
820 61e047a5 Phil Davis
			if (!empty($poolconf['tftp']) && ($poolconf['tftp'] != $dhcpifconf['tftp'])) {
821 cba980f6 jim-p
				$dhcpdconf .= "		option tftp-server-name \"{$poolconf['tftp']}\";\n";
822 61e047a5 Phil Davis
			}
823 cba980f6 jim-p
824
			// ldap-server
825 61e047a5 Phil Davis
			if (!empty($poolconf['ldap']) && ($poolconf['ldap'] != $dhcpifconf['ldap'])) {
826 cba980f6 jim-p
				$dhcpdconf .= "		option ldap-server \"{$poolconf['ldap']}\";\n";
827 61e047a5 Phil Davis
			}
828 cba980f6 jim-p
829
			// net boot information
830 61e047a5 Phil Davis
			if (isset($poolconf['netboot'])) {
831 cba980f6 jim-p
				if (!empty($poolconf['nextserver']) && ($poolconf['nextserver'] != $dhcpifconf['nextserver'])) {
832
					$dhcpdconf .= "		next-server {$poolconf['nextserver']};\n";
833
				}
834
				if (!empty($poolconf['filename']) && ($poolconf['filename'] != $dhcpifconf['filename'])) {
835
					$dhcpdconf .= "		filename \"{$poolconf['filename']}\";\n";
836
				}
837
				if (!empty($poolconf['rootpath']) && ($poolconf['rootpath'] != $dhcpifconf['rootpath'])) {
838
					$dhcpdconf .= "		option root-path \"{$poolconf['rootpath']}\";\n";
839
				}
840
			}
841
			$dhcpdconf .= "		range {$poolconf['range']['from']} {$poolconf['range']['to']};\n";
842
			$dhcpdconf .= "	}\n\n";
843
		}
844
// End of settings inside pools
845 a25183c5 Scott Ullrich
846 4208f7b1 timdufrane
		if ($dhcpifconf['gateway'] && $dhcpifconf['gateway'] != "none") {
847 5b237745 Scott Ullrich
			$routers = $dhcpifconf['gateway'];
848 c08a5659 smos
			$add_routers = true;
849 4208f7b1 timdufrane
		} elseif ($dhcpifconf['gateway'] == "none") {
850
			$add_routers = false;
851 c08a5659 smos
		} else {
852 3f141c9d Phil Davis
			$add_routers = $enable_add_routers;
853 a55e9c70 Ermal Lu?i
			$routers = $ifcfgip;
854 c08a5659 smos
		}
855 61e047a5 Phil Davis
		if ($add_routers) {
856 c08a5659 smos
			$dhcpdconf .= "	option routers {$routers};\n";
857 61e047a5 Phil Davis
		}
858 cba980f6 jim-p
859 c08a5659 smos
		$dhcpdconf .= <<<EOD
860 5b237745 Scott Ullrich
$dnscfg
861
862
EOD;
863 61e047a5 Phil Davis
		// default-lease-time
864
		if ($dhcpifconf['defaultleasetime']) {
865 5b237745 Scott Ullrich
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
866 61e047a5 Phil Davis
		}
867 518030b3 Scott Ullrich
868
		// max-lease-time
869 61e047a5 Phil Davis
		if ($dhcpifconf['maxleasetime']) {
870 5b237745 Scott Ullrich
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
871 61e047a5 Phil Davis
		}
872 a25183c5 Scott Ullrich
873 518030b3 Scott Ullrich
		// netbios-name*
874 5b237745 Scott Ullrich
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
875
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
876
			$dhcpdconf .= "	option netbios-node-type 8;\n";
877
		}
878 a25183c5 Scott Ullrich
879 518030b3 Scott Ullrich
		// ntp-servers
880 61e047a5 Phil Davis
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0]) {
881 ad171999 Seth Mos
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
882 61e047a5 Phil Davis
		}
883 ad171999 Seth Mos
884 518030b3 Scott Ullrich
		// tftp-server-name
885 61e047a5 Phil Davis
		if ($dhcpifconf['tftp'] <> "") {
886 6c23757b Martin Fuchs
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
887 61e047a5 Phil Davis
		}
888 6c23757b Martin Fuchs
889 518030b3 Scott Ullrich
		// Handle option, number rowhelper values
890
		$dhcpdconf .= "\n";
891 61e047a5 Phil Davis
		if ($dhcpifconf['numberoptions']['item']) {
892
			foreach ($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
893
				if (empty($item['type']) || $item['type'] == "text") {
894 678dfd0f Erik Fonnesbeck
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
895 61e047a5 Phil Davis
				} else {
896 678dfd0f Erik Fonnesbeck
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
897 61e047a5 Phil Davis
				}
898 518030b3 Scott Ullrich
			}
899
		}
900
901
		// ldap-server
902 61e047a5 Phil Davis
		if ($dhcpifconf['ldap'] <> "") {
903 6c23757b Martin Fuchs
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
904 61e047a5 Phil Davis
		}
905 6c23757b Martin Fuchs
906 518030b3 Scott Ullrich
		// net boot information
907 61e047a5 Phil Davis
		if (isset($dhcpifconf['netboot'])) {
908 a2578c27 Anthony Wrather
			if ($dhcpifconf['nextserver'] <> "") {
909
				$dhcpdconf .= "	next-server {$dhcpifconf['nextserver']};\n";
910
			}
911 fdb116a9 Donald A. Cupp Jr
			if (!empty($dhcpifconf['filename']) && !empty($dhcpifconf['filename32']) && !empty($dhcpifconf['filename64'])) {
912
				$dhcpdconf .= "	if option arch = 00:06 {\n";
913
				$dhcpdconf .= "		filename \"{$dhcpifconf['filename32']}\";\n";
914
				$dhcpdconf .= "	} else if option arch = 00:07 {\n";
915
				$dhcpdconf .= "		filename \"{$dhcpifconf['filename64']}\";\n";
916
				$dhcpdconf .= "	} else {\n";
917
				$dhcpdconf .= "		filename \"{$dhcpifconf['filename']}\";\n";
918
				$dhcpdconf .= "	}\n\n";
919
			} elseif (!empty($dhcpifconf['filename'])) {
920 4e9cd828 Seth Mos
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
921
			}
922 fdb116a9 Donald A. Cupp Jr
			if (!empty($dhcpifconf['rootpath'])) {
923 ca126e03 Martin Fuchs
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
924 cba980f6 jim-p
			}
925 4e9cd828 Seth Mos
		}
926 107e8acc Ovidiu Predescu
927 5b237745 Scott Ullrich
		$dhcpdconf .= <<<EOD
928
}
929
930
EOD;
931
932
		/* add static mappings */
933
		if (is_array($dhcpifconf['staticmap'])) {
934 a25183c5 Scott Ullrich
935 5b237745 Scott Ullrich
			$i = 0;
936
			foreach ($dhcpifconf['staticmap'] as $sm) {
937 449f1dd2 Will Boyce
				$dhcpdconf .= "host s_{$dhcpif}_{$i} {\n";
938
939 61e047a5 Phil Davis
				if ($sm['mac']) {
940
					$dhcpdconf .= "        hardware ethernet {$sm['mac']};\n";
941
				}
942 449f1dd2 Will Boyce
943 61e047a5 Phil Davis
				if ($sm['cid']) {
944
					$dhcpdconf .= "        option dhcp-client-identifier \"{$sm['cid']}\";\n";
945
				}
946 5b237745 Scott Ullrich
947 61e047a5 Phil Davis
				if ($sm['ipaddr']) {
948 5b237745 Scott Ullrich
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
949 61e047a5 Phil Davis
				}
950 a25183c5 Scott Ullrich
951 ad30055f Ermal Lu?i
				if ($sm['hostname']) {
952
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
953 46c5b763 pierrepomes
					$dhhostname = str_replace(".", "_", $dhhostname);
954 2f590513 smos
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
955 ad30055f Ermal Lu?i
				}
956 61e047a5 Phil Davis
				if ($sm['filename']) {
957 a2578c27 Anthony Wrather
					$dhcpdconf .= "	filename \"{$sm['filename']}\";\n";
958 61e047a5 Phil Davis
				}
959 a2578c27 Anthony Wrather
960 61e047a5 Phil Davis
				if ($sm['rootpath']) {
961 a2578c27 Anthony Wrather
					$dhcpdconf .= "	option root-path \"{$sm['rootpath']}\";\n";
962 61e047a5 Phil Davis
				}
963 80717709 Martin Fuchs
964 61e047a5 Phil Davis
				if ($sm['gateway'] && ($sm['gateway'] != $dhcpifconf['gateway'])) {
965 7309ff39 Renato Botelho
					$dhcpdconf .= "	option routers {$sm['gateway']};\n";
966 61e047a5 Phil Davis
				}
967 7309ff39 Renato Botelho
968
				$smdnscfg = "";
969
970
				if ($sm['domain'] && ($sm['domain'] != $dhcpifconf['domain'])) {
971
					$smdnscfg .= "	option domain-name \"{$sm['domain']}\";\n";
972
				}
973
974 61e047a5 Phil Davis
				if (!empty($sm['domainsearchlist']) && ($sm['domainsearchlist'] != $dhcpifconf['domainsearchlist'])) {
975 7309ff39 Renato Botelho
					$smdnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $sm['domainsearchlist'])) . "\";\n";
976
				}
977
978
				if (isset($sm['ddnsupdate'])) {
979 61e047a5 Phil Davis
					if (($sm['ddnsdomain'] <> "") && ($sm['ddnsdomain'] != $dhcpifconf['ddnsdomain'])) {
980 7309ff39 Renato Botelho
						$pdnscfg .= "		ddns-domainname \"{$sm['ddnsdomain']}\";\n";
981 61e047a5 Phil Davis
					}
982 7309ff39 Renato Botelho
					$pdnscfg .= "		ddns-update-style interim;\n";
983
				}
984
985
				if (is_array($sm['dnsserver']) && ($sm['dnsserver'][0]) && ($sm['dnsserver'][0] != $dhcpifconf['dnsserver'][0])) {
986
					$smdnscfg .= "	option domain-name-servers " . join(",", $sm['dnsserver']) . ";\n";
987
				}
988
				$dhcpdconf .= "{$smdnscfg}";
989
990
				// default-lease-time
991 61e047a5 Phil Davis
				if ($sm['defaultleasetime'] && ($sm['defaultleasetime'] != $dhcpifconf['defaultleasetime'])) {
992 7309ff39 Renato Botelho
					$dhcpdconf .= "	default-lease-time {$sm['defaultleasetime']};\n";
993 61e047a5 Phil Davis
				}
994 7309ff39 Renato Botelho
995
				// max-lease-time
996 61e047a5 Phil Davis
				if ($sm['maxleasetime'] && ($sm['maxleasetime'] != $dhcpifconf['maxleasetime'])) {
997 7309ff39 Renato Botelho
					$dhcpdconf .= "	max-lease-time {$sm['maxleasetime']};\n";
998 61e047a5 Phil Davis
				}
999 7309ff39 Renato Botelho
1000
				// netbios-name*
1001
				if (is_array($sm['winsserver']) && $sm['winsserver'][0] && ($sm['winsserver'][0] != $dhcpifconf['winsserver'][0])) {
1002
					$dhcpdconf .= "	option netbios-name-servers " . join(",", $sm['winsserver']) . ";\n";
1003
					$dhcpdconf .= "	option netbios-node-type 8;\n";
1004
				}
1005
1006
				// ntp-servers
1007 61e047a5 Phil Davis
				if (is_array($sm['ntpserver']) && $sm['ntpserver'][0] && ($sm['ntpserver'][0] != $dhcpifconf['ntpserver'][0])) {
1008 7309ff39 Renato Botelho
					$dhcpdconf .= "	option ntp-servers " . join(",", $sm['ntpserver']) . ";\n";
1009 61e047a5 Phil Davis
				}
1010 7309ff39 Renato Botelho
1011
				// tftp-server-name
1012 61e047a5 Phil Davis
				if (!empty($sm['tftp']) && ($sm['tftp'] != $dhcpifconf['tftp'])) {
1013 7309ff39 Renato Botelho
					$dhcpdconf .= "	option tftp-server-name \"{$sm['tftp']}\";\n";
1014 61e047a5 Phil Davis
				}
1015 7309ff39 Renato Botelho
1016 5b237745 Scott Ullrich
				$dhcpdconf .= "}\n";
1017
				$i++;
1018
			}
1019
		}
1020 a25183c5 Scott Ullrich
1021 6f9b8073 Ermal Luçi
		$dhcpdifs[] = get_real_interface($dhcpif);
1022 61e047a5 Phil Davis
		if ($newzone['domain-name']) {
1023
			if ($need_ddns_updates) {
1024 87019fc4 Andres Petralli
				$newzone['dns-servers'] = array($dhcpifconf['ddnsdomainprimary']);
1025
			}
1026 3df2dbfd jim-p
			$ddns_zones[] = $newzone;
1027 87019fc4 Andres Petralli
		}
1028 3df2dbfd jim-p
	}
1029
1030
	if ($need_ddns_updates) {
1031
		$dhcpdconf .= "ddns-update-style interim;\n";
1032 3cdef187 Andres Petralli
		$dhcpdconf .= "update-static-leases on;\n";
1033 87019fc4 Andres Petralli
1034
		$dhcpdconf .= dhcpdkey($dhcpifconf);
1035
		$dhcpdconf .= dhcpdzones($ddns_zones, $dhcpifconf);
1036 5b237745 Scott Ullrich
	}
1037
1038 abdd01f5 Ermal
	/* write dhcpd.conf */
1039
	if (!@file_put_contents("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", $dhcpdconf)) {
1040
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
1041
		unset($dhcpdconf);
1042
		return 1;
1043
	}
1044 928d4416 Ermal
	unset($dhcpdconf);
1045 2fb056d8 Seth Mos
1046
	/* create an empty leases database */
1047 61e047a5 Phil Davis
	if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
1048 abdd01f5 Ermal
		@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
1049 61e047a5 Phil Davis
	}
1050 2fb056d8 Seth Mos
1051 b075c1e2 Chris Buechler
	/* make sure there isn't a stale dhcpd.pid file, which can make dhcpd fail to start.   */
1052 61e047a5 Phil Davis
	/* if we get here, dhcpd has been killed and is not started yet                        */
1053 b075c1e2 Chris Buechler
	unlink_if_exists("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
1054
1055 2fb056d8 Seth Mos
	/* fire up dhcpd in a chroot */
1056 abdd01f5 Ermal
	if (count($dhcpdifs) > 0) {
1057 2fb056d8 Seth Mos
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
1058
			join(" ", $dhcpdifs));
1059
	}
1060
1061 61e047a5 Phil Davis
	if (platform_booting()) {
1062 2fb056d8 Seth Mos
		print "done.\n";
1063 61e047a5 Phil Davis
	}
1064 2fb056d8 Seth Mos
1065
	return 0;
1066
}
1067
1068 086cf944 Phil Davis
function dhcpdkey($dhcpifconf) {
1069 87019fc4 Andres Petralli
	$dhcpdconf = "";
1070 61e047a5 Phil Davis
	if ($dhcpifconf['ddnsdomainkeyname'] <> "" && $dhcpifconf['ddnsdomainkey'] <> "") {
1071 87019fc4 Andres Petralli
		$dhcpdconf .= "key {$dhcpifconf['ddnsdomainkeyname']} {\n";
1072
		$dhcpdconf .= "	algorithm hmac-md5;\n";
1073
		$dhcpdconf .= "	secret {$dhcpifconf['ddnsdomainkey']};\n";
1074
		$dhcpdconf .= "}\n";
1075
	}
1076
1077
	return $dhcpdconf;
1078
}
1079
1080 086cf944 Phil Davis
function dhcpdzones($ddns_zones, $dhcpifconf) {
1081 87019fc4 Andres Petralli
	$dhcpdconf = "";
1082
1083
	if (is_array($ddns_zones)) {
1084
		$added_zones = array();
1085
		foreach ($ddns_zones as $zone) {
1086 61e047a5 Phil Davis
			if (!is_array($zone) || empty($zone) || !is_array($zone['dns-servers'])) {
1087 87019fc4 Andres Petralli
				continue;
1088 61e047a5 Phil Davis
			}
1089 87019fc4 Andres Petralli
			$primary = $zone['dns-servers'][0];
1090
			$secondary = empty($zone['dns-servers'][1]) ? "" : $zone['dns-servers'][1];
1091
1092
			// Make sure we aren't using any invalid or IPv6 DNS servers.
1093
			if (!is_ipaddrv4($primary)) {
1094
				if (is_ipaddrv4($secondary)) {
1095
					$primary = $secondary;
1096
					$secondary = "";
1097
				} else {
1098
					continue;
1099
				}
1100
			}
1101
1102
			// We don't need to add zones multiple times.
1103
			if ($zone['domain-name'] && !in_array($zone['domain-name'], $added_zones)) {
1104
				$dhcpdconf .= "zone {$zone['domain-name']}. {\n";
1105
				$dhcpdconf .= "	primary {$primary};\n";
1106 61e047a5 Phil Davis
				if (is_ipaddrv4($secondary)) {
1107 87019fc4 Andres Petralli
					$dhcpdconf .= "	secondary {$secondary};\n";
1108 61e047a5 Phil Davis
				}
1109
				if ($dhcpifconf['ddnsdomainkeyname'] <> "" && $dhcpifconf['ddnsdomainkey'] <> "") {
1110
					$dhcpdconf .= "	key {$dhcpifconf['ddnsdomainkeyname']};\n";
1111
				}
1112 87019fc4 Andres Petralli
				$dhcpdconf .= "}\n";
1113
				$added_zones[] = $zone['domain-name'];
1114
			}
1115
			if ($zone['ptr-domain'] && !in_array($zone['ptr-domain'], $added_zones)) {
1116
				$dhcpdconf .= "zone {$zone['ptr-domain']} {\n";
1117
				$dhcpdconf .= "	primary {$primary};\n";
1118 61e047a5 Phil Davis
				if (is_ipaddrv4($secondary)) {
1119 87019fc4 Andres Petralli
					$dhcpdconf .= "	secondary {$secondary};\n";
1120 61e047a5 Phil Davis
				}
1121
				if ($dhcpifconf['ddnsdomainkeyname'] <> "" && $dhcpifconf['ddnsdomainkey'] <> "") {
1122
					$dhcpdconf .= "	key {$dhcpifconf['ddnsdomainkeyname']};\n";
1123
				}
1124 87019fc4 Andres Petralli
				$dhcpdconf .= "}\n";
1125
				$added_zones[] = $zone['ptr-domain'];
1126
			}
1127
		}
1128
	}
1129
1130
	return $dhcpdconf;
1131
}
1132
1133 92977616 Ermal
function services_dhcpdv6_configure($blacklist = array()) {
1134 2fb056d8 Seth Mos
	global $config, $g;
1135 107e8acc Ovidiu Predescu
1136 61e047a5 Phil Davis
	if ($g['services_dhcp_server_enable'] == false) {
1137 2fb056d8 Seth Mos
		return;
1138 61e047a5 Phil Davis
	}
1139 2fb056d8 Seth Mos
1140 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
1141 2fb056d8 Seth Mos
		$mt = microtime();
1142
		echo "services_dhcpd_configure($if) being called $mt\n";
1143
	}
1144 107e8acc Ovidiu Predescu
1145 2fb056d8 Seth Mos
	/* kill any running dhcpd */
1146 61e047a5 Phil Davis
	if (isvalidpid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid")) {
1147 bfb3e717 Seth Mos
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
1148 61e047a5 Phil Davis
	}
1149
	if (isvalidpid("{$g['varrun_path']}/dhcpleases6.pid")) {
1150 f7cd5647 smos
		killbypid("{$g['varrun_path']}/dhcpleases6.pid");
1151 61e047a5 Phil Davis
	}
1152 e9ab2ddb smos
1153 2fb056d8 Seth Mos
	/* DHCP enabled on any interfaces? */
1154 61e047a5 Phil Davis
	if (!is_dhcpv6_server_enabled()) {
1155 2fb056d8 Seth Mos
		return 0;
1156 61e047a5 Phil Davis
	}
1157 2fb056d8 Seth Mos
1158 285ef132 Ermal LUÇI
	if (platform_booting()) {
1159 2fb056d8 Seth Mos
		if ($g['platform'] != "pfSense") {
1160
			/* restore the leases, if we have them */
1161
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
1162
				$dhcprestore = "";
1163
				$dhcpreturn = "";
1164
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
1165
				$dhcprestore = implode(" ", $dhcprestore);
1166 61e047a5 Phil Davis
				if ($dhcpreturn <> 0) {
1167 2fb056d8 Seth Mos
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
1168
				}
1169
			}
1170
		}
1171
	}
1172
1173
	$syscfg = $config['system'];
1174 61e047a5 Phil Davis
	if (!is_array($config['dhcpdv6'])) {
1175 2fb056d8 Seth Mos
		$config['dhcpdv6'] = array();
1176 61e047a5 Phil Davis
	}
1177 2fb056d8 Seth Mos
	$dhcpdv6cfg = $config['dhcpdv6'];
1178
	$Iflist = get_configured_interface_list();
1179 e9ab2ddb smos
	$Iflist = array_merge($Iflist, get_configured_pppoe_server_interfaces());
1180
1181 107e8acc Ovidiu Predescu
1182 61e047a5 Phil Davis
	if (platform_booting()) {
1183 2fb056d8 Seth Mos
		echo "Starting DHCPv6 service...";
1184 61e047a5 Phil Davis
	} else {
1185 2fb056d8 Seth Mos
		sleep(1);
1186 61e047a5 Phil Davis
	}
1187 2fb056d8 Seth Mos
1188 a6610d82 smos
	/* we add a fake entry for interfaces that are set to track6 another WAN */
1189 abdd01f5 Ermal
	foreach ($Iflist as $ifname) {
1190 92977616 Ermal
		/* Do not put in the config an interface which is down */
1191 61e047a5 Phil Davis
		if (isset($blacklist[$ifname])) {
1192 92977616 Ermal
			continue;
1193 61e047a5 Phil Davis
		}
1194 abdd01f5 Ermal
		if (!empty($config['interfaces'][$ifname]['track6-interface'])) {
1195 06886ae3 Ermal
			$realif = get_real_interface($ifname, "inet6");
1196 c55a0f0c Ermal
			$ifcfgipv6 = get_interface_ipv6($ifname);
1197 61e047a5 Phil Davis
			if (!is_ipaddrv6($ifcfgipv6)) {
1198 c55a0f0c Ermal
				continue;
1199 61e047a5 Phil Davis
			}
1200 c55a0f0c Ermal
			$ifcfgipv6 = Net_IPv6::getNetmask($ifcfgipv6, 64);
1201 a6610d82 smos
			$trackifname = $config['interfaces'][$ifname]['track6-interface'];
1202
			$trackcfg = $config['interfaces'][$trackifname];
1203 319c2bfd smos
			$pdlen = calculate_ipv6_delegation_length($trackifname);
1204 a6610d82 smos
			$ifcfgipv6arr =explode(":", $ifcfgipv6);
1205
			$dhcpdv6cfg[$ifname] = array();
1206
			$dhcpdv6cfg[$ifname]['enable'] = true;
1207
			/* range */
1208
			$ifcfgipv6arr[7] = "1000";
1209 6fb66736 Ermal
			$dhcpdv6cfg[$ifname]['range'] = array();
1210 a6610d82 smos
			$dhcpdv6cfg[$ifname]['range']['from'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));
1211
			$ifcfgipv6arr[7] = "2000";
1212 91f026b0 ayvis
			$dhcpdv6cfg[$ifname]['range']['to'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));
1213 a6610d82 smos
			/* prefix length > 0? We can add dhcp6 prefix delegation server */
1214 61e047a5 Phil Davis
			if ($pdlen > 2) {
1215 c45b079d smos
				$pdlenmax = $pdlen;
1216 4aab9c6c smos
				$pdlenhalf = $pdlenmax -1;
1217
				$pdlenmin = (64 - ceil($pdlenhalf / 4));
1218 6fb66736 Ermal
				$dhcpdv6cfg[$ifname]['prefixrange'] = array();
1219 4aab9c6c smos
				$dhcpdv6cfg[$ifname]['prefixrange']['prefixlength'] = $pdlenmin;
1220
1221
				/* set the delegation start to half the current address block */
1222 c45b079d smos
				$range = Net_IPv6::parseAddress($ifcfgipv6, (64 - $pdlenmax));
1223 4aab9c6c smos
				$range['start'] = Net_IPv6::getNetmask($range['end'], (64 - $pdlenhalf));
1224
1225
				/* set the end range to a multiple of the prefix delegation size, required by dhcpd */
1226 c45b079d smos
				$range = Net_IPv6::parseAddress($range['end'], (64 - $pdlenhalf));
1227 4aab9c6c smos
				$range['end'] = Net_IPv6::getNetmask($range['end'], (64 - round($pdlen / 2)));
1228
1229 a6610d82 smos
				$dhcpdv6cfg[$ifname]['prefixrange']['from'] = Net_IPv6::compress($range['start']);
1230
				$dhcpdv6cfg[$ifname]['prefixrange']['to'] = Net_IPv6::compress($range['end']);
1231
			}
1232 8fd42722 Daniel Becker
			$dhcpdv6cfg[$ifname]['dns6ip'] = get_interface_ipv6($ifname);
1233 a6610d82 smos
		}
1234
	}
1235
1236 2fb056d8 Seth Mos
	$custoptionsv6 = "";
1237 107e8acc Ovidiu Predescu
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
1238 61e047a5 Phil Davis
		if (is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
1239
			foreach ($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
1240 2fb056d8 Seth Mos
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
1241
			}
1242
		}
1243
	}
1244
1245 61e047a5 Phil Davis
	if (isset($dhcpv6ifconf['netboot']) && !empty($dhcpv6ifconf['bootfile_url'])) {
1246 bd942860 Renato Botelho
		$custoptionsv6 .= "option dhcp6.bootfile-url code 59 = string;\n";
1247 61e047a5 Phil Davis
	}
1248 bd942860 Renato Botelho
1249 2fb056d8 Seth Mos
	$dhcpdv6conf = <<<EOD
1250 107e8acc Ovidiu Predescu
1251 2fb056d8 Seth Mos
option domain-name "{$syscfg['domain']}";
1252
option ldap-server code 95 = text;
1253
option domain-search-list code 119 = text;
1254 547f1e65 Renato Botelho
{$custoptionsv6}
1255 2fb056d8 Seth Mos
default-lease-time 7200;
1256
max-lease-time 86400;
1257
log-facility local7;
1258
one-lease-per-client true;
1259
deny duplicates;
1260
ping-check true;
1261 87019fc4 Andres Petralli
update-conflict-detection false;
1262 2fb056d8 Seth Mos
1263
EOD;
1264
1265 61e047a5 Phil Davis
	if (!isset($dhcpv6ifconf['disableauthoritative'])) {
1266 2fb056d8 Seth Mos
		$dhcpdv6conf .= "authoritative;\n";
1267 61e047a5 Phil Davis
	}
1268 2fb056d8 Seth Mos
1269 61e047a5 Phil Davis
	if (isset($dhcpv6ifconf['alwaysbroadcast'])) {
1270 2fb056d8 Seth Mos
		$dhcpdv6conf .= "always-broadcast on\n";
1271 61e047a5 Phil Davis
	}
1272 2fb056d8 Seth Mos
1273
	$dhcpdv6ifs = array();
1274
1275 693833cb Seth Mos
	$dhcpv6num = 0;
1276 87019fc4 Andres Petralli
	$nsupdate = false;
1277
1278 693833cb Seth Mos
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
1279
1280 87019fc4 Andres Petralli
		$ddns_zones = array();
1281
1282 693833cb Seth Mos
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
1283
1284 61e047a5 Phil Davis
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]) || !isset($ifcfgv6['enable'])) {
1285 693833cb Seth Mos
			continue;
1286 61e047a5 Phil Davis
		}
1287 693833cb Seth Mos
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
1288
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
1289 d57293a4 Seth Mos
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
1290 693833cb Seth Mos
1291 1944af41 Ermal
		if ($is_olsr_enabled == true) {
1292 61e047a5 Phil Davis
			if ($dhcpv6ifconf['netmask']) {
1293 bfb3e717 Seth Mos
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
1294 61e047a5 Phil Davis
			}
1295 1944af41 Ermal
		}
1296 693833cb Seth Mos
1297
		$dnscfgv6 = "";
1298
1299
		if ($dhcpv6ifconf['domain']) {
1300 3c009080 Seth Mos
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
1301 693833cb Seth Mos
		}
1302 107e8acc Ovidiu Predescu
1303 61e047a5 Phil Davis
		if ($dhcpv6ifconf['domainsearchlist'] <> "") {
1304 a3de8b9e Pierre POMES
			$dnscfgv6 .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpv6ifconf['domainsearchlist'])) . "\";\n";
1305 61e047a5 Phil Davis
		}
1306 693833cb Seth Mos
1307
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
1308 61e047a5 Phil Davis
			if ($dhcpv6ifconf['ddnsdomain'] <> "") {
1309 3c009080 Seth Mos
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
1310 693833cb Seth Mos
			}
1311 3c009080 Seth Mos
			$dnscfgv6 .= "	ddns-update-style interim;\n";
1312 87019fc4 Andres Petralli
			$nsupdate = true;
1313 693833cb Seth Mos
		}
1314
1315
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
1316
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
1317 f4620b36 Chris Buechler
		} else if (((isset($config['dnsmasq']['enable'])) || isset($config['unbound']['enable'])) && (is_ipaddrv6($ifcfgipv6))) {
1318 693833cb Seth Mos
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
1319
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1320 2521266a Seth Mos
			$dns_arrv6 = array();
1321 61e047a5 Phil Davis
			foreach ($syscfg['dnsserver'] as $dnsserver) {
1322 1944af41 Ermal
				if (is_ipaddrv6($dnsserver)) {
1323 2521266a Seth Mos
					$dns_arrv6[] = $dnsserver;
1324
				}
1325
			}
1326 61e047a5 Phil Davis
			if (!empty($dns_arrv6)) {
1327 2816c5a1 Seth Mos
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
1328 61e047a5 Phil Davis
			}
1329 693833cb Seth Mos
		}
1330
1331 87019fc4 Andres Petralli
		if ($dhcpv6ifconf['domain']) {
1332
			$newzone = array();
1333 61e047a5 Phil Davis
			$newzone['domain-name'] = $dhcpv6ifconf['domain'];
1334 87019fc4 Andres Petralli
			$newzone['dns-servers'][] = $dhcpv6ifconf['ddnsdomainprimary'];
1335
			$ddns_zones[] = $newzone;
1336
		}
1337
1338 1944af41 Ermal
		if (is_ipaddrv6($ifcfgipv6)) {
1339
			$dhcpdv6conf .= "subnet6 {$subnetv6}/{$ifcfgsnv6}";
1340 e9ab2ddb smos
		} else {
1341 88cc00db Ermal
			$subnet6 = gen_subnetv6($dhcpv6ifconf['range']['from'], "64");
1342 1944af41 Ermal
			$dhcpdv6conf .= "subnet6 {$subnet6}/64";
1343 abdd01f5 Ermal
		}
1344 1944af41 Ermal
		$dhcpdv6conf .= " {\n";
1345 693833cb Seth Mos
1346
		$dhcpdv6conf .= <<<EOD
1347
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
1348
$dnscfgv6
1349
1350
EOD;
1351 bfb3e717 Seth Mos
1352 1944af41 Ermal
		if (is_ipaddrv6($dhcpv6ifconf['prefixrange']['from']) && is_ipaddrv6($dhcpv6ifconf['prefixrange']['to'])) {
1353 978b8f50 Chris Buechler
			$dhcpdv6conf .= "	prefix6 {$dhcpv6ifconf['prefixrange']['from']} {$dhcpv6ifconf['prefixrange']['to']} /{$dhcpv6ifconf['prefixrange']['prefixlength']};\n";
1354 bfb3e717 Seth Mos
		}
1355 70da4172 Jean Cyr
		if (is_ipaddrv6($dhcpv6ifconf['dns6ip'])) {
1356 8fd42722 Daniel Becker
			$dhcpdv6conf .= "	option dhcp6.name-servers {$dhcpv6ifconf['dns6ip']};\n";
1357 70da4172 Jean Cyr
		}
1358 61e047a5 Phil Davis
		// default-lease-time
1359
		if ($dhcpv6ifconf['defaultleasetime']) {
1360 693833cb Seth Mos
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
1361 61e047a5 Phil Davis
		}
1362 693833cb Seth Mos
1363
		// max-lease-time
1364 61e047a5 Phil Davis
		if ($dhcpv6ifconf['maxleasetime']) {
1365 693833cb Seth Mos
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
1366 61e047a5 Phil Davis
		}
1367 693833cb Seth Mos
1368
		// ntp-servers
1369 4096fe5d smos
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) {
1370
			$ntpservers = array();
1371 61e047a5 Phil Davis
			foreach ($dhcpv6ifconf['ntpserver'] as $ntpserver) {
1372
				if (is_ipaddrv6($ntpserver)) {
1373 4096fe5d smos
					$ntpservers[] = $ntpserver;
1374 61e047a5 Phil Davis
				}
1375 4096fe5d smos
			}
1376 61e047a5 Phil Davis
			if (count($ntpservers) > 0) {
1377 4096fe5d smos
				$dhcpdv6conf .= "       option dhcp6.sntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
1378 61e047a5 Phil Davis
			}
1379 4096fe5d smos
		}
1380 693833cb Seth Mos
		// tftp-server-name
1381 7d504365 smos
		/* Needs ISC DHCPD support
1382 61e047a5 Phil Davis
		 if ($dhcpv6ifconf['tftp'] <> "") {
1383 693833cb Seth Mos
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
1384 61e047a5 Phil Davis
		 }
1385 7d504365 smos
		*/
1386 693833cb Seth Mos
1387
		// Handle option, number rowhelper values
1388
		$dhcpdv6conf .= "\n";
1389 1944af41 Ermal
		if ($dhcpv6ifconf['numberoptions']['item']) {
1390 61e047a5 Phil Davis
			foreach ($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
1391 693833cb Seth Mos
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
1392
			}
1393
		}
1394
1395
		// ldap-server
1396 61e047a5 Phil Davis
		if ($dhcpv6ifconf['ldap'] <> "") {
1397 693833cb Seth Mos
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
1398 61e047a5 Phil Davis
		}
1399 693833cb Seth Mos
1400
		// net boot information
1401 61e047a5 Phil Davis
		if (isset($dhcpv6ifconf['netboot'])) {
1402 bd942860 Renato Botelho
			if (!empty($dhcpv6ifconf['bootfile_url'])) {
1403
				$dhcpdv6conf .= "	option dhcp6.bootfile-url \"{$dhcpv6ifconf['bootfile_url']}\";\n";
1404 abdd01f5 Ermal
			}
1405
		}
1406 107e8acc Ovidiu Predescu
1407 1c903aa4 Ermal
		$dhcpdv6conf .= "}\n";
1408 693833cb Seth Mos
1409
		/* add static mappings */
1410 2fb056d8 Seth Mos
		/* Needs to use DUID */
1411 693833cb Seth Mos
		if (is_array($dhcpv6ifconf['staticmap'])) {
1412
			$i = 0;
1413
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
1414
				$dhcpdv6conf .= <<<EOD
1415
host s_{$dhcpv6if}_{$i} {
1416 2fb056d8 Seth Mos
	host-identifier option dhcp6.client-id {$sm['duid']};
1417 693833cb Seth Mos
1418
EOD;
1419 61e047a5 Phil Davis
				if ($sm['ipaddrv6']) {
1420 2fb056d8 Seth Mos
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
1421 61e047a5 Phil Davis
				}
1422 693833cb Seth Mos
1423
				if ($sm['hostname']) {
1424
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
1425
					$dhhostname = str_replace(".", "_", $dhhostname);
1426
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
1427
				}
1428 61e047a5 Phil Davis
				if ($sm['filename']) {
1429 a2578c27 Anthony Wrather
					$dhcpdv6conf .= "	filename \"{$sm['filename']}\";\n";
1430 61e047a5 Phil Davis
				}
1431 a2578c27 Anthony Wrather
1432 61e047a5 Phil Davis
				if ($sm['rootpath']) {
1433 a2578c27 Anthony Wrather
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
1434 61e047a5 Phil Davis
				}
1435 693833cb Seth Mos
1436
				$dhcpdv6conf .= "}\n";
1437
				$i++;
1438
			}
1439
		}
1440 107e8acc Ovidiu Predescu
1441 61e047a5 Phil Davis
		if ($dhcpv6ifconf['domain']) {
1442 87019fc4 Andres Petralli
			$dhcpdv6conf .= dhcpdkey($dhcpv6ifconf);
1443
			$dhcpdv6conf .= dhcpdzones($ddns_zones, $dhcpv6ifconf);
1444
		}
1445
1446 57006646 Renato Botelho
		if ($config['dhcpdv6'][$dhcpv6if]['ramode'] <> "unmanaged" && isset($config['interfaces'][$dhcpv6if]['enable'])) {
1447 61e047a5 Phil Davis
			if (preg_match("/poes/si", $dhcpv6if)) {
1448 e9ab2ddb smos
				/* magic here */
1449
				$dhcpdv6ifs = array_merge($dhcpdv6ifs, get_pppoes_child_interfaces($dhcpv6if));
1450
			} else {
1451 1944af41 Ermal
				$realif = get_real_interface($dhcpv6if, "inet6");
1452 029b377a Ermal
				if (stristr("$realif", "bridge")) {
1453
					$mac = get_interface_mac($realif);
1454
					$v6address = generate_ipv6_from_mac($mac);
1455
					/* Create link local address for bridges */
1456 e9ab2ddb smos
					mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
1457
				}
1458 029b377a Ermal
				$realif = escapeshellcmd($realif);
1459
				$dhcpdv6ifs[] = $realif;
1460 656f1763 Seth Mos
			}
1461 de140730 Seth Mos
		}
1462 693833cb Seth Mos
	}
1463
1464 61e047a5 Phil Davis
	if ($nsupdate) {
1465 87019fc4 Andres Petralli
		$dhcpdv6conf .= "ddns-update-style interim;\n";
1466 61e047a5 Phil Davis
	} else {
1467 87019fc4 Andres Petralli
		$dhcpdv6conf .= "ddns-update-style none;\n";
1468
	}
1469
1470 abdd01f5 Ermal
	/* write dhcpdv6.conf */
1471
	if (!@file_put_contents("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", $dhcpdv6conf)) {
1472 1c903aa4 Ermal
		log_error("Error: cannot open {$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf in services_dhcpdv6_configure().\n");
1473 61e047a5 Phil Davis
		if (platform_booting()) {
1474 1c903aa4 Ermal
			printf("Error: cannot open {$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf in services_dhcpdv6_configure().\n");
1475 61e047a5 Phil Davis
		}
1476 abdd01f5 Ermal
		unset($dhcpdv6conf);
1477
		return 1;
1478
	}
1479 928d4416 Ermal
	unset($dhcpdv6conf);
1480
1481 693833cb Seth Mos
	/* create an empty leases v6 database */
1482 61e047a5 Phil Davis
	if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases")) {
1483 abdd01f5 Ermal
		@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1484 61e047a5 Phil Davis
	}
1485 107e8acc Ovidiu Predescu
1486 61e047a5 Phil Davis
	/* make sure there isn't a stale dhcpdv6.pid file, which may make dhcpdv6 fail to start.  */
1487
	/* if we get here, dhcpdv6 has been killed and is not started yet                         */
1488
	unlink_if_exists("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
1489 b075c1e2 Chris Buechler
1490 68a0e4fc Scott Ullrich
	/* fire up dhcpd in a chroot */
1491 abdd01f5 Ermal
	if (count($dhcpdv6ifs) > 0) {
1492 2fb056d8 Seth Mos
		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 " .
1493 2a1bd027 Seth Mos
			join(" ", $dhcpdv6ifs));
1494 cb7d18d5 Renato Botelho
		mwexec("/usr/local/sbin/dhcpleases6 -c \"/usr/local/bin/php-cgi -f /usr/local/sbin/prefixes.php|/bin/sh\" -l {$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1495 2a1bd027 Seth Mos
	}
1496 61e047a5 Phil Davis
	if (platform_booting()) {
1497 f1a44a3a Carlos Eduardo Ramos
		print gettext("done.") . "\n";
1498 61e047a5 Phil Davis
	}
1499 a25183c5 Scott Ullrich
1500 5b237745 Scott Ullrich
	return 0;
1501
}
1502
1503 41997fbb Ermal Luci
function services_igmpproxy_configure() {
1504 61e047a5 Phil Davis
	global $config, $g;
1505 41997fbb Ermal Luci
1506 61e047a5 Phil Davis
	/* kill any running igmpproxy */
1507
	killbyname("igmpproxy");
1508 41997fbb Ermal Luci
1509 61e047a5 Phil Davis
	if (!is_array($config['igmpproxy']['igmpentry']) || (count($config['igmpproxy']['igmpentry']) == 0)) {
1510 41997fbb Ermal Luci
		return 1;
1511 61e047a5 Phil Davis
	}
1512 41997fbb Ermal Luci
1513 61e047a5 Phil Davis
	$iflist = get_configured_interface_list();
1514 f206afb5 Ermal
1515 61e047a5 Phil Davis
	$igmpconf = <<<EOD
1516 41997fbb Ermal Luci
1517
##------------------------------------------------------
1518
## Enable Quickleave mode (Sends Leave instantly)
1519
##------------------------------------------------------
1520
quickleave
1521
1522
EOD;
1523
1524 61e047a5 Phil Davis
	foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
1525
		unset($iflist[$igmpcf['ifname']]);
1526
		$realif = get_real_interface($igmpcf['ifname']);
1527
		if (empty($igmpcf['threshold'])) {
1528
			$threshld = 1;
1529
		} else {
1530
			$threshld = $igmpcf['threshold'];
1531
		}
1532
		$igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
1533
1534
		if ($igmpcf['address'] <> "") {
1535
			$item = explode(" ", $igmpcf['address']);
1536
			foreach ($item as $iww) {
1537
				$igmpconf .= "altnet {$iww}\n";
1538
			}
1539
		}
1540
		$igmpconf .= "\n";
1541
	}
1542
	foreach ($iflist as $ifn) {
1543
		$realif = get_real_interface($ifn);
1544
		$igmpconf .= "phyint {$realif} disabled\n";
1545
	}
1546 3bae60be Ermal
	$igmpconf .= "\n";
1547 41997fbb Ermal Luci
1548 61e047a5 Phil Davis
	$igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
1549
	if (!$igmpfl) {
1550
		log_error(gettext("Could not write Igmpproxy configuration file!"));
1551
		return;
1552
	}
1553
	fwrite($igmpfl, $igmpconf);
1554
	fclose($igmpfl);
1555 928d4416 Ermal
	unset($igmpconf);
1556 41997fbb Ermal Luci
1557 d629f1ca Renato Botelho
	/* NOTE: -d4 means everything LOG_WARNING and smaller */
1558 61e047a5 Phil Davis
	mwexec("/usr/local/sbin/igmpproxy -d4 -c {$g['tmp_path']}/igmpproxy.conf");
1559
	log_error(gettext("Started IGMP proxy service."));
1560 41997fbb Ermal Luci
1561 61e047a5 Phil Davis
	return 0;
1562 41997fbb Ermal Luci
}
1563
1564 5b237745 Scott Ullrich
function services_dhcrelay_configure() {
1565 f19d3b7a Scott Ullrich
	global $config, $g;
1566 6fa9f38c Renato Botelho
1567 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
1568 acd910bf Scott Ullrich
		$mt = microtime();
1569 f19d3b7a Scott Ullrich
		echo "services_dhcrelay_configure() being called $mt\n";
1570 acd910bf Scott Ullrich
	}
1571 a25183c5 Scott Ullrich
1572 5b237745 Scott Ullrich
	/* kill any running dhcrelay */
1573
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1574 a25183c5 Scott Ullrich
1575 2f06cc3f Ermal
	$dhcrelaycfg =& $config['dhcrelay'];
1576 a25183c5 Scott Ullrich
1577 5b237745 Scott Ullrich
	/* DHCPRelay enabled on any interfaces? */
1578 61e047a5 Phil Davis
	if (!isset($dhcrelaycfg['enable'])) {
1579 5b237745 Scott Ullrich
		return 0;
1580 61e047a5 Phil Davis
	}
1581 a25183c5 Scott Ullrich
1582 61e047a5 Phil Davis
	if (platform_booting()) {
1583 f1a44a3a Carlos Eduardo Ramos
		echo gettext("Starting DHCP relay service...");
1584 61e047a5 Phil Davis
	} else {
1585 5b237745 Scott Ullrich
		sleep(1);
1586 61e047a5 Phil Davis
	}
1587 a25183c5 Scott Ullrich
1588 2f06cc3f Ermal
	$iflist = get_configured_interface_list();
1589 a25183c5 Scott Ullrich
1590 2f06cc3f Ermal
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1591
	foreach ($dhcifaces as $dhcrelayif) {
1592
		if (!isset($iflist[$dhcrelayif]) ||
1593 61e047a5 Phil Davis
		    link_interface_to_bridge($dhcrelayif)) {
1594 5b237745 Scott Ullrich
			continue;
1595 61e047a5 Phil Davis
		}
1596 a25183c5 Scott Ullrich
1597 61e047a5 Phil Davis
		if (is_ipaddr(get_interface_ip($dhcrelayif))) {
1598 2f06cc3f Ermal
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1599 61e047a5 Phil Davis
		}
1600 5b237745 Scott Ullrich
	}
1601 f791f28d Chris Buechler
	
1602
	$srvips = explode(",", $dhcrelaycfg['server']);	
1603 c58879a9 Ermal LUÇI
	if (!is_array($srvips)) {
1604 f791f28d Chris Buechler
		log_error("No destination IP has been configured!");
1605 c58879a9 Ermal LUÇI
		return;
1606
	}
1607
1608 5b237745 Scott Ullrich
	$dhcrelayifs = array_unique($dhcrelayifs);
1609
1610
	/* fire up dhcrelay */
1611 24997966 Ermal
	if (empty($dhcrelayifs)) {
1612 5a171fb7 Warren Baker
		log_error("No suitable interface found for running dhcrelay!");
1613 24997966 Ermal
		return; /* XXX */
1614
	}
1615
1616 6c07db48 Phil Davis
	$cmd = "/usr/local/sbin/dhcrelay -i " . implode(" -i ", $dhcrelayifs);
1617 5b237745 Scott Ullrich
1618 61e047a5 Phil Davis
	if (isset($dhcrelaycfg['agentoption'])) {
1619 6c07db48 Phil Davis
		$cmd .= " -a -m replace";
1620 61e047a5 Phil Davis
	}
1621 5b237745 Scott Ullrich
1622 2f06cc3f Ermal
	$cmd .= " " . implode(" ", $srvips);
1623 5b237745 Scott Ullrich
	mwexec($cmd);
1624 928d4416 Ermal
	unset($cmd);
1625 a25183c5 Scott Ullrich
1626 5b237745 Scott Ullrich
	return 0;
1627
}
1628
1629 b7a15cf8 Seth Mos
function services_dhcrelay6_configure() {
1630
	global $config, $g;
1631 6fa9f38c Renato Botelho
1632 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
1633 b7a15cf8 Seth Mos
		$mt = microtime();
1634 874f099a Phil Davis
		echo "services_dhcrelay6_configure() being called $mt\n";
1635 b7a15cf8 Seth Mos
	}
1636
1637
	/* kill any running dhcrelay */
1638
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1639
1640
	$dhcrelaycfg =& $config['dhcrelay6'];
1641
1642
	/* DHCPv6 Relay enabled on any interfaces? */
1643 61e047a5 Phil Davis
	if (!isset($dhcrelaycfg['enable'])) {
1644 b7a15cf8 Seth Mos
		return 0;
1645 61e047a5 Phil Davis
	}
1646 b7a15cf8 Seth Mos
1647 61e047a5 Phil Davis
	if (platform_booting()) {
1648 b7a15cf8 Seth Mos
		echo gettext("Starting DHCPv6 relay service...");
1649 61e047a5 Phil Davis
	} else {
1650 b7a15cf8 Seth Mos
		sleep(1);
1651 61e047a5 Phil Davis
	}
1652 b7a15cf8 Seth Mos
1653
	$iflist = get_configured_interface_list();
1654
1655
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1656
	foreach ($dhcifaces as $dhcrelayif) {
1657
		if (!isset($iflist[$dhcrelayif]) ||
1658 086cf944 Phil Davis
		    link_interface_to_bridge($dhcrelayif)) {
1659 b7a15cf8 Seth Mos
			continue;
1660 086cf944 Phil Davis
		}
1661 b7a15cf8 Seth Mos
1662 61e047a5 Phil Davis
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif))) {
1663 b7a15cf8 Seth Mos
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1664 61e047a5 Phil Davis
		}
1665 b7a15cf8 Seth Mos
	}
1666 69dd7088 Michael Tharp
	$dhcrelayifs = array_unique($dhcrelayifs);
1667 b7a15cf8 Seth Mos
1668
	$srvips = explode(",", $dhcrelaycfg['server']);
1669 f791f28d Chris Buechler
	if (!is_array($srvips)) {
1670
		log_error("No destination IP has been configured!");
1671
		return;
1672 b7a15cf8 Seth Mos
	}
1673
1674
	/* fire up dhcrelay */
1675 61e047a5 Phil Davis
	if (empty($dhcrelayifs) || empty($srvifaces)) {
1676 b7a15cf8 Seth Mos
		log_error("No suitable interface found for running dhcrelay -6!");
1677
		return; /* XXX */
1678
	}
1679
1680 54a9d71d Phil Davis
	$cmd = "/usr/local/sbin/dhcrelay -6 -pf \"{$g['varrun_path']}/dhcrelay6.pid\"";
1681 69dd7088 Michael Tharp
	foreach ($dhcrelayifs as $dhcrelayif) {
1682
		$cmd .= " -l {$dhcrelayif}";
1683
	}
1684
	foreach ($srvifaces as $srviface) {
1685
		$cmd .= " -u \"{$srviface}\"";
1686
	}
1687 b7a15cf8 Seth Mos
	mwexec($cmd);
1688 928d4416 Ermal
	unset($cmd);
1689 b7a15cf8 Seth Mos
1690
	return 0;
1691
}
1692
1693 181d7c95 Ermal Luçi
function services_dyndns_configure_client($conf) {
1694
1695 61e047a5 Phil Davis
	if (!isset($conf['enable'])) {
1696 65996399 Ermal
		return;
1697 61e047a5 Phil Davis
	}
1698 d2946062 Ermal
1699 181d7c95 Ermal Luçi
	/* load up the dyndns.class */
1700
	require_once("dyndns.class");
1701
1702
	$dns = new updatedns($dnsService = $conf['type'],
1703
		$dnsHost = $conf['host'],
1704
		$dnsUser = $conf['username'],
1705
		$dnsPass = $conf['password'],
1706 3aa55bbe Phil Davis
		$dnsWildcard = $conf['wildcard'],
1707 107e8acc Ovidiu Predescu
		$dnsMX = $conf['mx'],
1708 f3b2b2a4 Yehuda Katz
		$dnsIf = "{$conf['interface']}",
1709
		$dnsBackMX = NULL,
1710
		$dnsServer = NULL,
1711
		$dnsPort = NULL,
1712 37f3e704 Matt Corallo
		$dnsUpdateURL = "{$conf['updateurl']}",
1713 cd132e86 Edson Brandi
		$forceUpdate = $conf['force'],
1714 6c07db48 Phil Davis
		$dnsZoneID = $conf['zoneid'],
1715
		$dnsTTL = $conf['ttl'],
1716 37f3e704 Matt Corallo
		$dnsResultMatch = "{$conf['resultmatch']}",
1717
		$dnsRequestIf = "{$conf['requestif']}",
1718 1e503870 Phil Davis
		$dnsID = "{$conf['id']}",
1719 aa79f351 Sebastian Chrostek
		$dnsVerboseLog = $conf['verboselog'],
1720
		$curlIpresolveV4 = $conf['curl_ipresolve_v4'],
1721
		$curlSslVerifypeer = $conf['curl_ssl_verifypeer']);
1722 181d7c95 Ermal Luçi
}
1723
1724 0be93267 Ermal Lu?i
function services_dyndns_configure($int = "") {
1725 f19d3b7a Scott Ullrich
	global $config, $g;
1726 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
1727 59a63553 Scott Ullrich
		$mt = microtime();
1728
		echo "services_dyndns_configure() being called $mt\n";
1729
	}
1730
1731 67ee1ec5 Ermal Luçi
	$dyndnscfg = $config['dyndnses']['dyndns'];
1732 017817c2 smos
	$gwgroups = return_gateway_groups_array();
1733 67ee1ec5 Ermal Luçi
	if (is_array($dyndnscfg)) {
1734 61e047a5 Phil Davis
		if (platform_booting()) {
1735 f1a44a3a Carlos Eduardo Ramos
			echo gettext("Starting DynDNS clients...");
1736 61e047a5 Phil Davis
		}
1737 181d7c95 Ermal Luçi
1738 67ee1ec5 Ermal Luçi
		foreach ($dyndnscfg as $dyndns) {
1739 786ff5eb phildd
			if ((empty($int)) || ($int == $dyndns['interface']) || (is_array($gwgroups[$dyndns['interface']]))) {
1740 1e503870 Phil Davis
				$dyndns['verboselog'] = isset($dyndns['verboselog']);
1741 d9bdc020 Sebastian Chrostek
				$dyndns['curl_ipresolve_v4'] = isset($dyndns['curl_ipresolve_v4']);
1742
				$dyndns['curl_ssl_verifypeer'] = isset($dyndns['curl_ssl_verifypeer']);
1743 768eb89c smos
				services_dyndns_configure_client($dyndns);
1744
				sleep(1);
1745
			}
1746 67ee1ec5 Ermal Luçi
		}
1747 59a63553 Scott Ullrich
1748 61e047a5 Phil Davis
		if (platform_booting()) {
1749 f1a44a3a Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1750 61e047a5 Phil Davis
		}
1751 59a63553 Scott Ullrich
	}
1752
1753
	return 0;
1754
}
1755
1756 0e3aeb6b Phil Davis
function dyndnsCheckIP($int) {
1757 873e4b28 phildd
	global $config;
1758 0e3aeb6b Phil Davis
	$ip_address = get_interface_ip($int);
1759
	if (is_private_ip($ip_address)) {
1760 873e4b28 phildd
		$gateways_status = return_gateways_status(true);
1761
		// If the gateway for this interface is down, then the external check cannot work.
1762
		// Avoid the long wait for the external check to timeout.
1763 61e047a5 Phil Davis
		if (stristr($gateways_status[$config['interfaces'][$int]['gateway']]['status'], "down")) {
1764 873e4b28 phildd
			return "down";
1765 61e047a5 Phil Davis
		}
1766 5244c510 Florian Asche
		$hosttocheck = "http://checkip.dyndns.org";
1767
		$ip_ch = curl_init($hosttocheck);
1768 0e3aeb6b Phil Davis
		curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1);
1769
		curl_setopt($ip_ch, CURLOPT_SSL_VERIFYPEER, FALSE);
1770 e1eee3d2 Renato Botelho
		curl_setopt($ip_ch, CURLOPT_INTERFACE, 'host!' . $ip_address);
1771 181386d6 Florian Asche
		curl_setopt($ip_ch, CURLOPT_CONNECTTIMEOUT, '30');
1772
		curl_setopt($ip_ch, CURLOPT_TIMEOUT, 120);
1773 3c6f29c0 Florian Asche
		curl_setopt($ip_ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1774 0e3aeb6b Phil Davis
		$ip_result_page = curl_exec($ip_ch);
1775
		curl_close($ip_ch);
1776
		$ip_result_decoded = urldecode($ip_result_page);
1777
		preg_match('=Current IP Address: (.*)</body>=siU', $ip_result_decoded, $matches);
1778
		$ip_address = trim($matches[1]);
1779
	}
1780
	return $ip_address;
1781
}
1782
1783 5b237745 Scott Ullrich
function services_dnsmasq_configure() {
1784 f19d3b7a Scott Ullrich
	global $config, $g;
1785 6a01ea44 Bill Marquette
	$return = 0;
1786 107e8acc Ovidiu Predescu
1787 683992fc stilez
	// hard coded args: will be removed to avoid duplication if specified in custom_options
1788
	$standard_args = array(
1789
		"dns-forward-max" => "--dns-forward-max=5000",
1790
		"cache-size" => "--cache-size=10000",
1791
		"local-ttl" => "--local-ttl=1"
1792
	);
1793
1794
1795 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
1796 acd910bf Scott Ullrich
		$mt = microtime();
1797 f19d3b7a Scott Ullrich
		echo "services_dnsmasq_configure() being called $mt\n";
1798 acd910bf Scott Ullrich
	}
1799
1800 5b237745 Scott Ullrich
	/* kill any running dnsmasq */
1801 61e047a5 Phil Davis
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid")) {
1802 d224df18 Ermal
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1803 61e047a5 Phil Davis
	}
1804 5b237745 Scott Ullrich
1805
	if (isset($config['dnsmasq']['enable'])) {
1806 a25183c5 Scott Ullrich
1807 61e047a5 Phil Davis
		if (platform_booting()) {
1808 f1a44a3a Carlos Eduardo Ramos
			echo gettext("Starting DNS forwarder...");
1809 61e047a5 Phil Davis
		} else {
1810 5b237745 Scott Ullrich
			sleep(1);
1811 61e047a5 Phil Davis
		}
1812 5b237745 Scott Ullrich
1813 61e047a5 Phil Davis
		/* generate hosts file */
1814 086cf944 Phil Davis
		if (system_hosts_generate() != 0) {
1815 61e047a5 Phil Davis
			$return = 1;
1816
		}
1817 cbc6a13f Chris Buechler
1818 5b237745 Scott Ullrich
		$args = "";
1819 a25183c5 Scott Ullrich
1820 0261381a Ermal
		if (isset($config['dnsmasq']['regdhcp'])) {
1821
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1822
		}
1823 107e8acc Ovidiu Predescu
1824 e6c49e3d jim-p
		/* Setup listen port, if non-default */
1825 61e047a5 Phil Davis
		if (is_port($config['dnsmasq']['port'])) {
1826 e6c49e3d jim-p
			$args .= " --port={$config['dnsmasq']['port']} ";
1827 61e047a5 Phil Davis
		}
1828 e6c49e3d jim-p
1829 b4323f39 jim-p
		$listen_addresses = "";
1830 61e047a5 Phil Davis
		if (isset($config['dnsmasq']['interface'])) {
1831 b4323f39 jim-p
			$interfaces = explode(",", $config['dnsmasq']['interface']);
1832
			foreach ($interfaces as $interface) {
1833 55909a9a Ermal
				if (is_ipaddrv4($interface)) {
1834 b4323f39 jim-p
					$listen_addresses .= " --listen-address={$interface} ";
1835 55909a9a Ermal
				} else if (is_ipaddrv6($interface)) {
1836
					/*
1837
					 * XXX: Since dnsmasq does not support link-local address
1838
					 * with scope specified. These checks are being done.
1839
					 */
1840
					if (is_linklocal($interface) && strstr($interface, "%")) {
1841
						$tmpaddrll6 = explode("%", $interface);
1842
						$listen_addresses .= " --listen-address={$tmpaddrll6[0]} ";
1843 61e047a5 Phil Davis
					} else {
1844 55909a9a Ermal
						$listen_addresses .= " --listen-address={$interface} ";
1845 61e047a5 Phil Davis
					}
1846 9e7e2c94 Chris Buechler
				} else if (strstr($interface, "_vip")) {
1847
					$laddr = get_configured_carp_interface_list($interface);
1848 61e047a5 Phil Davis
					if (is_ipaddr($laddr)) {
1849 9e7e2c94 Chris Buechler
						$listen_addresses .= " --listen-address={$laddr} ";
1850 61e047a5 Phil Davis
					}
1851 b4323f39 jim-p
				} else {
1852
					$if = get_real_interface($interface);
1853
					if (does_interface_exist($if)) {
1854 89f171b0 Ermal LUÇI
						$laddr = get_interface_ip($interface);
1855 61e047a5 Phil Davis
						if (is_ipaddrv4($laddr)) {
1856 b4323f39 jim-p
							$listen_addresses .= " --listen-address={$laddr} ";
1857 61e047a5 Phil Davis
						}
1858 89f171b0 Ermal LUÇI
						$laddr6 = get_interface_ipv6($interface);
1859 b77d19c7 Ermal
						if (is_ipaddrv6($laddr6) && !isset($config['dnsmasq']['strictbind'])) {
1860
							/*
1861
							 * XXX: Since dnsmasq does not support link-local address
1862
							 * with scope specified. These checks are being done.
1863
							 */
1864
							if (is_linklocal($laddr6) && strstr($laddr6, "%")) {
1865
								$tmpaddrll6 = explode("%", $laddr6);
1866
								$listen_addresses .= " --listen-address={$tmpaddrll6[0]} ";
1867 61e047a5 Phil Davis
							} else {
1868 b77d19c7 Ermal
								$listen_addresses .= " --listen-address={$laddr6} ";
1869 61e047a5 Phil Davis
							}
1870 b77d19c7 Ermal
						}
1871 b4323f39 jim-p
					}
1872
				}
1873
			}
1874
			if (!empty($listen_addresses)) {
1875
				$args .= " {$listen_addresses} ";
1876 61e047a5 Phil Davis
				if (isset($config['dnsmasq']['strictbind'])) {
1877 b4323f39 jim-p
					$args .= " --bind-interfaces ";
1878 61e047a5 Phil Davis
				}
1879 b4323f39 jim-p
			}
1880
		}
1881
1882 fc27d3f4 Phil Davis
		/* If selected, then first forward reverse lookups for private IPv4 addresses to nowhere. */
1883 153613e3 Phil Davis
		/* Only make entries for reverse domains that do not have a matching domain override. */
1884 0a7985ba Phil Davis
		if (isset($config['dnsmasq']['no_private_reverse'])) {
1885
			/* Note: Carrier Grade NAT (CGN) addresses 100.64.0.0/10 are intentionally not here. */
1886
			/* End-users should not be aware of CGN addresses, so reverse lookups for these should not happen. */
1887
			/* Just the pfSense WAN might get a CGN address from an ISP. */
1888 153613e3 Phil Davis
1889
			// Build an array of domain overrides to help in checking for matches.
1890
			$override_a = array();
1891
			if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1892
				foreach ($config['dnsmasq']['domainoverrides'] as $override) {
1893
					$override_a[$override['domain']] = "y";
1894
				}
1895
			}
1896
1897
			// Build an array of the private reverse lookup domain names
1898
			$reverse_domain_a = array("10.in-addr.arpa", "168.192.in-addr.arpa");
1899
			// Unfortunately the 172.16.0.0/12 range does not map nicely to the in-addr.arpa scheme.
1900 61e047a5 Phil Davis
			for ($subnet_num = 16; $subnet_num < 32; $subnet_num++) {
1901 153613e3 Phil Davis
				$reverse_domain_a[] = "$subnet_num.172.in-addr.arpa";
1902
			}
1903
1904
			// Set the --server parameter to nowhere for each reverse domain name that was not specifically specified in a domain override.
1905 61e047a5 Phil Davis
			foreach ($reverse_domain_a as $reverse_domain) {
1906
				if (!isset($override_a[$reverse_domain])) {
1907 153613e3 Phil Davis
					$args .= " --server=/$reverse_domain/ ";
1908 61e047a5 Phil Davis
				}
1909 0a7985ba Phil Davis
			}
1910 153613e3 Phil Davis
			unset($override_a);
1911
			unset($reverse_domain_a);
1912 0a7985ba Phil Davis
		}
1913
1914 fc27d3f4 Phil Davis
		/* Setup forwarded domains */
1915
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1916 61e047a5 Phil Davis
			foreach ($config['dnsmasq']['domainoverrides'] as $override) {
1917
				if ($override['ip'] == "!") {
1918 fc27d3f4 Phil Davis
					$override[ip] = "";
1919 61e047a5 Phil Davis
				}
1920 fc27d3f4 Phil Davis
				$args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1921
			}
1922
		}
1923
1924 2c46f11f Scott Ullrich
		/* Allow DNS Rebind for forwarded domains */
1925 29721fe6 Scott Ullrich
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1926 61e047a5 Phil Davis
			if (!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1927
				foreach ($config['dnsmasq']['domainoverrides'] as $override) {
1928 30d20e7d Scott Ullrich
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1929
				}
1930 2c46f11f Scott Ullrich
			}
1931
		}
1932 91adc5c1 Scott Ullrich
1933 61e047a5 Phil Davis
		if (!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1934 30d20e7d Scott Ullrich
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1935 61e047a5 Phil Davis
		}
1936 30d20e7d Scott Ullrich
1937 96ea7162 N0YB
		if (isset($config['dnsmasq']['strict_order'])) {
1938
			$args .= " --strict-order ";
1939
		}
1940
1941
		if (isset($config['dnsmasq']['domain_needed'])) {
1942
			$args .= " --domain-needed ";
1943
		}
1944
1945 61e047a5 Phil Davis
		if ($config['dnsmasq']['custom_options']) {
1946 683992fc stilez
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c) {
1947 071f6059 jim-p
				$args .= " " . escapeshellarg("--{$c}");
1948 683992fc stilez
				$p = explode('=', $c);
1949 61e047a5 Phil Davis
				if (array_key_exists($p[0], $standard_args)) {
1950 683992fc stilez
					unset($standard_args[$p[0]]);
1951 61e047a5 Phil Davis
				}
1952 683992fc stilez
			}
1953 61e047a5 Phil Davis
		}
1954 41567e06 jim-p
		$args .= ' ' . implode(' ', array_values($standard_args));
1955 8f9bffbc Andrew Thompson
1956 5b237745 Scott Ullrich
		/* run dnsmasq */
1957 683992fc stilez
		$cmd = "/usr/local/sbin/dnsmasq --all-servers {$dns_rebind} {$args}";
1958 b4323f39 jim-p
		//log_error("dnsmasq command: {$cmd}");
1959
		mwexec_bg($cmd);
1960 928d4416 Ermal
		unset($args);
1961 5b237745 Scott Ullrich
1962 61e047a5 Phil Davis
		system_dhcpleases_configure();
1963 0a5a8df9 Warren Baker
1964 61e047a5 Phil Davis
		if (platform_booting()) {
1965 f1a44a3a Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1966 61e047a5 Phil Davis
		}
1967 5b237745 Scott Ullrich
	}
1968 a25183c5 Scott Ullrich
1969 285ef132 Ermal LUÇI
	if (!platform_booting()) {
1970 086cf944 Phil Davis
		if (services_dhcpd_configure() != 0) {
1971 6a01ea44 Bill Marquette
			$return = 1;
1972 61e047a5 Phil Davis
		}
1973 5b237745 Scott Ullrich
	}
1974
1975 6a01ea44 Bill Marquette
	return $return;
1976 5b237745 Scott Ullrich
}
1977
1978 175dc861 Warren Baker
function services_unbound_configure() {
1979
	global $config, $g;
1980
	$return = 0;
1981
1982
	if (isset($config['system']['developerspew'])) {
1983
		$mt = microtime();
1984
		echo "services_unbound_configure() being called $mt\n";
1985
	}
1986
1987
	// kill any running Unbound instance
1988 61e047a5 Phil Davis
	if (file_exists("{$g['varrun_path']}/unbound.pid")) {
1989 175dc861 Warren Baker
		sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1990 61e047a5 Phil Davis
	}
1991 175dc861 Warren Baker
1992
	if (isset($config['unbound']['enable'])) {
1993 61e047a5 Phil Davis
		if (platform_booting()) {
1994 5bb1c495 Warren Baker
			echo gettext("Starting DNS Resolver...");
1995 61e047a5 Phil Davis
		} else {
1996 175dc861 Warren Baker
			sleep(1);
1997 61e047a5 Phil Davis
		}
1998 175dc861 Warren Baker
1999 b3c6783f Renato Botelho
		/* generate hosts file */
2000 086cf944 Phil Davis
		if (system_hosts_generate() != 0) {
2001 b3c6783f Renato Botelho
			$return = 1;
2002 61e047a5 Phil Davis
		}
2003 b3c6783f Renato Botelho
2004 175dc861 Warren Baker
		require_once('/etc/inc/unbound.inc');
2005
		sync_unbound_service();
2006 61e047a5 Phil Davis
		if (platform_booting()) {
2007 175dc861 Warren Baker
			echo gettext("done.") . "\n";
2008 61e047a5 Phil Davis
		}
2009 0a5a8df9 Warren Baker
2010 61e047a5 Phil Davis
		system_dhcpleases_configure();
2011 175dc861 Warren Baker
	}
2012
2013 285ef132 Ermal LUÇI
	if (!platform_booting()) {
2014 086cf944 Phil Davis
		if (services_dhcpd_configure() != 0) {
2015 175dc861 Warren Baker
			$return = 1;
2016 61e047a5 Phil Davis
		}
2017 175dc861 Warren Baker
	}
2018
2019
	return $return;
2020
}
2021
2022 5b237745 Scott Ullrich
function services_snmpd_configure() {
2023 f19d3b7a Scott Ullrich
	global $config, $g;
2024 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
2025 acd910bf Scott Ullrich
		$mt = microtime();
2026 f19d3b7a Scott Ullrich
		echo "services_snmpd_configure() being called $mt\n";
2027
	}
2028 5b237745 Scott Ullrich
2029
	/* kill any running snmpd */
2030
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
2031 dd18038e Ermal
	sleep(2);
2032 61e047a5 Phil Davis
	if (is_process_running("bsnmpd")) {
2033 a976fa82 Scott Ullrich
		mwexec("/usr/bin/killall bsnmpd", true);
2034 61e047a5 Phil Davis
	}
2035 5b237745 Scott Ullrich
2036
	if (isset($config['snmpd']['enable'])) {
2037 a25183c5 Scott Ullrich
2038 61e047a5 Phil Davis
		if (platform_booting()) {
2039 f1a44a3a Carlos Eduardo Ramos
			echo gettext("Starting SNMP daemon... ");
2040 61e047a5 Phil Davis
		}
2041 5b237745 Scott Ullrich
2042
		/* generate snmpd.conf */
2043
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
2044
		if (!$fd) {
2045 086cf944 Phil Davis
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"), "\n");
2046 5b237745 Scott Ullrich
			return 1;
2047
		}
2048 a25183c5 Scott Ullrich
2049 142da8f7 John Fleming
2050 5b237745 Scott Ullrich
		$snmpdconf = <<<EOD
2051 d47a8a69 Scott Ullrich
location := "{$config['snmpd']['syslocation']}"
2052
contact := "{$config['snmpd']['syscontact']}"
2053
read := "{$config['snmpd']['rocommunity']}"
2054 142da8f7 John Fleming
2055
EOD;
2056
2057
/* No docs on what write strings do there for disable for now.
2058 61e047a5 Phil Davis
		if (isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])) {
2059
			$snmpdconf .= <<<EOD
2060 142da8f7 John Fleming
# write string
2061
write := "{$config['snmpd']['rwcommunity']}"
2062
2063
EOD;
2064
		}
2065
*/
2066
2067
2068 61e047a5 Phil Davis
		if (isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])) {
2069
			$snmpdconf .= <<<EOD
2070 142da8f7 John Fleming
# SNMP Trap support.
2071 dbeeb008 John Fleming
traphost := {$config['snmpd']['trapserver']}
2072
trapport := {$config['snmpd']['trapserverport']}
2073
trap := "{$config['snmpd']['trapstring']}"
2074 142da8f7 John Fleming
2075
2076
EOD;
2077
		}
2078
2079 dadf8ebb jim-p
		$platform = trim(file_get_contents('/etc/platform'));
2080 61e047a5 Phil Davis
		if (($platform == "pfSense") && ($g['product_name'] != "pfSense")) {
2081 e52cb3a4 jim-p
			$platform = $g['product_name'];
2082 61e047a5 Phil Davis
		}
2083 dadf8ebb jim-p
		$sysDescr = "{$g['product_name']} " . php_uname("n") .
2084 5779ade6 Renato Botelho
			" {$g['product_version']} {$platform} " . php_uname("s") .
2085 dadf8ebb jim-p
			" " . php_uname("r") . " " . php_uname("m");
2086 142da8f7 John Fleming
2087
		$snmpdconf .= <<<EOD
2088 d47a8a69 Scott Ullrich
system := 1     # pfSense
2089
%snmpd
2090 dadf8ebb jim-p
sysDescr			= "{$sysDescr}"
2091 d47a8a69 Scott Ullrich
begemotSnmpdDebugDumpPdus       = 2
2092
begemotSnmpdDebugSyslogPri      = 7
2093
begemotSnmpdCommunityString.0.1 = $(read)
2094 142da8f7 John Fleming
2095
EOD;
2096
2097
/* No docs on what write strings do there for disable for now.
2098 61e047a5 Phil Davis
		if (isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])) {
2099
			$snmpdconf .= <<<EOD
2100 142da8f7 John Fleming
begemotSnmpdCommunityString.0.2 = $(write)
2101
2102
EOD;
2103
		}
2104
*/
2105
2106 c7f44ae0 Scott Ullrich
2107 61e047a5 Phil Davis
		if (isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])) {
2108
			$snmpdconf .= <<<EOD
2109 142da8f7 John Fleming
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
2110
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
2111
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
2112
2113
EOD;
2114
		}
2115
2116
2117
		$snmpdconf .= <<<EOD
2118 d47a8a69 Scott Ullrich
begemotSnmpdCommunityDisable    = 1
2119 03ba7a0f John Fleming
2120
EOD;
2121
2122 de5aec97 jim-p
		if (isset($config['snmpd']['bindlan'])) {
2123
			$config['snmpd']['bindip'] = 'lan';
2124
			unset($config['snmpd']['bindlan']);
2125
		}
2126 c82b2c3f jim-p
		$bind_to_ip = "0.0.0.0";
2127 61e047a5 Phil Davis
		if (isset($config['snmpd']['bindip'])) {
2128 c82b2c3f jim-p
			if (is_ipaddr($config['snmpd']['bindip'])) {
2129
				$bind_to_ip = $config['snmpd']['bindip'];
2130
			} else {
2131
				$if = get_real_interface($config['snmpd']['bindip']);
2132 61e047a5 Phil Davis
				if (does_interface_exist($if)) {
2133 89f171b0 Ermal LUÇI
					$bind_to_ip = get_interface_ip($config['snmpd']['bindip']);
2134 61e047a5 Phil Davis
				}
2135 c82b2c3f jim-p
			}
2136 7cbad422 Scott Ullrich
		}
2137
2138 61e047a5 Phil Davis
		if (is_port($config['snmpd']['pollport'])) {
2139
			$snmpdconf .= <<<EOD
2140 7cbad422 Scott Ullrich
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
2141 03ba7a0f John Fleming
2142
EOD;
2143
2144
		}
2145
2146
		$snmpdconf .= <<<EOD
2147 d47a8a69 Scott Ullrich
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
2148
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
2149 142da8f7 John Fleming
2150 03ba7a0f John Fleming
# These are bsnmp macros not php vars.
2151 9cc8c59e Scott Ullrich
sysContact      = $(contact)
2152
sysLocation     = $(location)
2153
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
2154 142da8f7 John Fleming
2155 d47a8a69 Scott Ullrich
snmpEnableAuthenTraps = 2
2156 03ba7a0f John Fleming
2157
EOD;
2158
2159 61e047a5 Phil Davis
		if (is_array($config['snmpd']['modules'])) {
2160
			if (isset($config['snmpd']['modules']['mibii'])) {
2161 03ba7a0f John Fleming
			$snmpdconf .= <<<EOD
2162 d47a8a69 Scott Ullrich
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
2163 03ba7a0f John Fleming
2164
EOD;
2165 61e047a5 Phil Davis
			}
2166 03ba7a0f John Fleming
2167 61e047a5 Phil Davis
			if (isset($config['snmpd']['modules']['netgraph'])) {
2168
				$snmpdconf .= <<<EOD
2169 d47a8a69 Scott Ullrich
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
2170
%netgraph
2171
begemotNgControlNodeName = "snmpd"
2172 03ba7a0f John Fleming
2173
EOD;
2174 61e047a5 Phil Davis
			}
2175 03ba7a0f John Fleming
2176 61e047a5 Phil Davis
			if (isset($config['snmpd']['modules']['pf'])) {
2177
				$snmpdconf .= <<<EOD
2178 d47a8a69 Scott Ullrich
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
2179 95fb49e8 Seth Mos
2180
EOD;
2181 61e047a5 Phil Davis
			}
2182 95fb49e8 Seth Mos
2183 a03974a3 Renato Botelho
			if (isset($config['snmpd']['modules']['hostres'])) {
2184
				/* XXX: hostres module crashes APU - ticket #4403 */
2185
				$specplatform = system_identify_specific_platform();
2186
				if ($specplatform['name'] == 'APU') {
2187
					log_error("'Host Resources' SNMP module was ignored because it can potentially crash system on APU boards");
2188
				} else {
2189
					$snmpdconf .= <<<EOD
2190 95fb49e8 Seth Mos
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
2191
2192
EOD;
2193 a03974a3 Renato Botelho
				}
2194
				unset($specplatform);
2195 61e047a5 Phil Davis
			}
2196 05036071 Renato Botelho
2197 61e047a5 Phil Davis
			if (isset($config['snmpd']['modules']['bridge'])) {
2198
				$snmpdconf .= <<<EOD
2199 95fb49e8 Seth Mos
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
2200 d47a8a69 Scott Ullrich
# config must end with blank line
2201 5b237745 Scott Ullrich
2202
EOD;
2203 61e047a5 Phil Davis
			}
2204
			if (isset($config['snmpd']['modules']['ucd'])) {
2205 671914b2 jim-p
				$snmpdconf .= <<<EOD
2206
begemotSnmpdModulePath."ucd"     = "/usr/local/lib/snmp_ucd.so"
2207
2208
EOD;
2209
			}
2210 61e047a5 Phil Davis
			if (isset($config['snmpd']['modules']['regex'])) {
2211 671914b2 jim-p
				$snmpdconf .= <<<EOD
2212
begemotSnmpdModulePath."regex"     = "/usr/local/lib/snmp_regex.so"
2213
2214
EOD;
2215
			}
2216 03ba7a0f John Fleming
		}
2217 5b237745 Scott Ullrich
2218
		fwrite($fd, $snmpdconf);
2219
		fclose($fd);
2220 928d4416 Ermal
		unset($snmpdconf);
2221 5b237745 Scott Ullrich
2222 7cbad422 Scott Ullrich
		if (isset($config['snmpd']['bindlan'])) {
2223
			$bindlan = "";
2224
		}
2225
2226 853e003a Scott Ullrich
		/* run bsnmpd */
2227
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
2228 7cbad422 Scott Ullrich
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
2229 5b237745 Scott Ullrich
2230 61e047a5 Phil Davis
		if (platform_booting()) {
2231 f1a44a3a Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
2232 61e047a5 Phil Davis
		}
2233 5b237745 Scott Ullrich
	}
2234
2235
	return 0;
2236
}
2237
2238 7c9da7be jim-p
function services_dnsupdate_process($int = "", $updatehost = "", $forced = false) {
2239 f19d3b7a Scott Ullrich
	global $config, $g;
2240 61e047a5 Phil Davis
	if (isset($config['system']['developerspew'])) {
2241 acd910bf Scott Ullrich
		$mt = microtime();
2242 f19d3b7a Scott Ullrich
		echo "services_dnsupdate_process() being called $mt\n";
2243 acd910bf Scott Ullrich
	}
2244 f19d3b7a Scott Ullrich
2245 a23d7248 Scott Ullrich
	/* Dynamic DNS updating active? */
2246 67ee1ec5 Ermal Luçi
	if (is_array($config['dnsupdates']['dnsupdate'])) {
2247 7c9da7be jim-p
		$notify_text = "";
2248 67ee1ec5 Ermal Luçi
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
2249 61e047a5 Phil Davis
			if (!isset($dnsupdate['enable'])) {
2250 2ec2a374 Ermal Lu?i
				continue;
2251 61e047a5 Phil Davis
			}
2252
			if (!empty($int) && $int != $dnsupdate['interface']) {
2253 67ee1ec5 Ermal Luçi
				continue;
2254 61e047a5 Phil Davis
			}
2255
			if (!empty($updatehost) && ($updatehost != $dnsupdate['host'])) {
2256 7c9da7be jim-p
				continue;
2257 61e047a5 Phil Davis
			}
2258 67ee1ec5 Ermal Luçi
2259 2ec2a374 Ermal Lu?i
			/* determine interface name */
2260 26586f7a Ermal Lu?i
			$if = get_real_interface($dnsupdate['interface']);
2261 61e047a5 Phil Davis
2262
			if (isset($dnsupdate['usepublicip'])) {
2263
				$wanip = dyndnsCheckIP($dnsupdate['interface']);
2264
			} else {
2265
				$wanip = get_interface_ip($dnsupdate['interface']);
2266
			}
2267
2268 fc1f4960 jim-p
			$wanipv6 = get_interface_ipv6($dnsupdate['interface']);
2269 7c9da7be jim-p
			$cacheFile = "{$g['conf_path']}/dyndns_{$dnsupdate['interface']}_rfc2136_" . escapeshellarg($dnsupdate['host']) . "_{$dnsupdate['server']}.cache";
2270
			$currentTime = time();
2271
2272
			if ($wanip || $wanipv6) {
2273 67ee1ec5 Ermal Luçi
				$keyname = $dnsupdate['keyname'];
2274
				/* trailing dot */
2275 61e047a5 Phil Davis
				if (substr($keyname, -1) != ".") {
2276 67ee1ec5 Ermal Luçi
					$keyname .= ".";
2277 61e047a5 Phil Davis
				}
2278 67ee1ec5 Ermal Luçi
2279
				$hostname = $dnsupdate['host'];
2280
				/* trailing dot */
2281 61e047a5 Phil Davis
				if (substr($hostname, -1) != ".") {
2282 67ee1ec5 Ermal Luçi
					$hostname .= ".";
2283 61e047a5 Phil Davis
				}
2284 67ee1ec5 Ermal Luçi
2285
				/* write private key file
2286
				   this is dumb - public and private keys are the same for HMAC-MD5,
2287
				   but nsupdate insists on having both */
2288
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
2289 8ec0a8bc jim-p
				$privkey = <<<EOD
2290 a23d7248 Scott Ullrich
Private-key-format: v1.2
2291
Algorithm: 157 (HMAC)
2292 67ee1ec5 Ermal Luçi
Key: {$dnsupdate['keydata']}
2293 a23d7248 Scott Ullrich
2294
EOD;
2295 67ee1ec5 Ermal Luçi
				fwrite($fd, $privkey);
2296
				fclose($fd);
2297
2298
				/* write public key file */
2299
				if ($dnsupdate['keytype'] == "zone") {
2300
					$flags = 257;
2301
					$proto = 3;
2302
				} else if ($dnsupdate['keytype'] == "host") {
2303
					$flags = 513;
2304
					$proto = 3;
2305
				} else if ($dnsupdate['keytype'] == "user") {
2306
					$flags = 0;
2307
					$proto = 2;
2308
				}
2309 c7f44ae0 Scott Ullrich
2310 26586f7a Ermal Lu?i
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.key", "w");
2311 67ee1ec5 Ermal Luçi
				fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n");
2312
				fclose($fd);
2313
2314
				/* generate update instructions */
2315
				$upinst = "";
2316 61e047a5 Phil Davis
				if (!empty($dnsupdate['server'])) {
2317 67ee1ec5 Ermal Luçi
					$upinst .= "server {$dnsupdate['server']}\n";
2318 61e047a5 Phil Davis
				}
2319 7c9da7be jim-p
2320
				if (file_exists($cacheFile)) {
2321
					list($cachedipv4, $cacheTimev4) = explode("|", file_get_contents($cacheFile));
2322
				}
2323
				if (file_exists("{$cacheFile}.ipv6")) {
2324
					list($cachedipv6, $cacheTimev6) = explode("|", file_get_contents("{$cacheFile}.ipv6"));
2325
				}
2326
2327
				// 25 Days
2328
				$maxCacheAgeSecs = 25 * 24 * 60 * 60;
2329
				$need_update = false;
2330 819a603c jim-p
2331
				conf_mount_rw();
2332 fc1f4960 jim-p
				/* Update IPv4 if we have it. */
2333 ea08d2b2 Robert Nelson
				if (is_ipaddrv4($wanip) && $dnsupdate['recordtype'] != "AAAA") {
2334 7c9da7be jim-p
					if (($wanip != $cachedipv4) || (($currentTime - $cacheTimev4) > $maxCacheAgeSecs) || $forced) {
2335
						$upinst .= "update delete {$dnsupdate['host']}. A\n";
2336
						$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} A {$wanip}\n";
2337
						$notify_text .= sprintf(gettext("DynDNS updated IP Address (A) for {$dnsupdate['host']} on %s (%s) to %s"), convert_real_interface_to_friendly_descr($if), $if, $wanip) . "\n";
2338
						@file_put_contents($cacheFile, "{$wanip}|{$currentTime}");
2339
						log_error("phpDynDNS: updating cache file {$cacheFile}: {$wanip}");
2340
						$need_update = true;
2341
					} else {
2342
						log_error("phpDynDNS: Not updating {$dnsupdate['host']} A record because the IP address has not changed.");
2343
					}
2344 61e047a5 Phil Davis
				} else {
2345 7c9da7be jim-p
					@unlink($cacheFile);
2346 61e047a5 Phil Davis
				}
2347 7c9da7be jim-p
2348 fc1f4960 jim-p
				/* Update IPv6 if we have it. */
2349 ea08d2b2 Robert Nelson
				if (is_ipaddrv6($wanipv6) && $dnsupdate['recordtype'] != "A") {
2350 7c9da7be jim-p
					if (($wanipv6 != $cachedipv6) || (($currentTime - $cacheTimev6) > $maxCacheAgeSecs) || $forced) {
2351
						$upinst .= "update delete {$dnsupdate['host']}. AAAA\n";
2352
						$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} AAAA {$wanipv6}\n";
2353
						$notify_text .= sprintf(gettext("DynDNS updated IPv6 Address (AAAA) for {$dnsupdate['host']} on %s (%s) to %s"), convert_real_interface_to_friendly_descr($if), $if, $wanipv6) . "\n";
2354
						@file_put_contents("{$cacheFile}.ipv6", "{$wanipv6}|{$currentTime}");
2355
						log_error("phpDynDNS: updating cache file {$cacheFile}.ipv6: {$wanipv6}");
2356
						$need_update = true;
2357
					} else {
2358
						log_error("phpDynDNS: Not updating {$dnsupdate['host']} AAAA record because the IPv6 address has not changed.");
2359
					}
2360 61e047a5 Phil Davis
				} else {
2361 7c9da7be jim-p
					@unlink("{$cacheFile}.ipv6");
2362 61e047a5 Phil Davis
				}
2363 819a603c jim-p
				conf_mount_ro();
2364 67ee1ec5 Ermal Luçi
2365 7c9da7be jim-p
				$upinst .= "\n";	/* mind that trailing newline! */
2366 107e8acc Ovidiu Predescu
2367 7c9da7be jim-p
				if ($need_update) {
2368
					@file_put_contents("{$g['varetc_path']}/nsupdatecmds{$i}", $upinst);
2369
					unset($upinst);
2370
					/* invoke nsupdate */
2371 22cc6582 Renato Botelho
					$cmd = "/usr/local/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
2372 61e047a5 Phil Davis
					if (isset($dnsupdate['usetcp'])) {
2373 7c9da7be jim-p
						$cmd .= " -v";
2374 61e047a5 Phil Davis
					}
2375 7c9da7be jim-p
					$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
2376
					mwexec_bg($cmd);
2377
					unset($cmd);
2378
				}
2379 67ee1ec5 Ermal Luçi
			}
2380 a23d7248 Scott Ullrich
		}
2381 7c9da7be jim-p
		if (!empty($notify_text)) {
2382
			notify_all_remote($notify_text);
2383
		}
2384 a23d7248 Scott Ullrich
	}
2385 c7f44ae0 Scott Ullrich
2386 a23d7248 Scott Ullrich
	return 0;
2387 5b237745 Scott Ullrich
}
2388
2389 1071e028 Scott Ullrich
/* configure cron service */
2390
function configure_cron() {
2391
	global $g, $config;
2392 e7d3fc15 Ermal
2393 251ca022 Scott Ullrich
	conf_mount_rw();
2394 1071e028 Scott Ullrich
	/* preserve existing crontab entries */
2395 e7d3fc15 Ermal
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2396 107e8acc Ovidiu Predescu
2397 e7d3fc15 Ermal
	for ($i = 0; $i < count($crontab_contents); $i++) {
2398
		$cron_item =& $crontab_contents[$i];
2399
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
2400
			array_splice($crontab_contents, $i - 1);
2401 1071e028 Scott Ullrich
			break;
2402
		}
2403
	}
2404 e7d3fc15 Ermal
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
2405 107e8acc Ovidiu Predescu
2406
2407 1071e028 Scott Ullrich
	if (is_array($config['cron']['item'])) {
2408
		$crontab_contents .= "#\n";
2409 f1a44a3a Carlos Eduardo Ramos
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2410 61e047a5 Phil Davis
		$crontab_contents .= "# " .gettext("Created:") . " " . date("F j, Y, g:i a") . "\n";
2411 1071e028 Scott Ullrich
		$crontab_contents .= "#\n";
2412
2413 992f60d0 Renato Botelho
		if (isset($config['system']['proxyurl']) && !empty($config['system']['proxyurl'])) {
2414
			$http_proxy = $config['system']['proxyurl'];
2415 61e047a5 Phil Davis
			if (isset($config['system']['proxyport']) && !empty($config['system']['proxyport'])) {
2416 992f60d0 Renato Botelho
				$http_proxy .= ':' . $config['system']['proxyport'];
2417 61e047a5 Phil Davis
			}
2418 992f60d0 Renato Botelho
			$crontab_contents .= "HTTP_PROXY={$http_proxy}";
2419
		}
2420
2421 1071e028 Scott Ullrich
		foreach ($config['cron']['item'] as $item) {
2422
			$crontab_contents .= "\n{$item['minute']}\t";
2423
			$crontab_contents .= "{$item['hour']}\t";
2424
			$crontab_contents .= "{$item['mday']}\t";
2425
			$crontab_contents .= "{$item['month']}\t";
2426
			$crontab_contents .= "{$item['wday']}\t";
2427
			$crontab_contents .= "{$item['who']}\t";
2428
			$crontab_contents .= "{$item['command']}";
2429
		}
2430 107e8acc Ovidiu Predescu
2431 1071e028 Scott Ullrich
		$crontab_contents .= "\n#\n";
2432 f1a44a3a Carlos Eduardo Ramos
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2433
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2434 1071e028 Scott Ullrich
		$crontab_contents .= "#\n\n";
2435
	}
2436 107e8acc Ovidiu Predescu
2437 1071e028 Scott Ullrich
	/* please maintain the newline at the end of file */
2438
	file_put_contents("/etc/crontab", $crontab_contents);
2439 c2d97111 Ermal
	unset($crontab_contents);
2440 41d507a5 Scott Ullrich
2441 8fe38524 doktornotor
	/* make sure that cron is running and start it if it got killed somehow */
2442
	if (!is_process_running("cron")) {
2443
		exec("cd /tmp && /usr/sbin/cron -s 2>/dev/null");
2444
	} else {
2445 41d507a5 Scott Ullrich
	/* do a HUP kill to force sync changes */
2446 dca795b7 Renato Botelho
	sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
2447 8fe38524 doktornotor
	}
2448 41d507a5 Scott Ullrich
2449 6d6bca27 Ermal Lu?i
	conf_mount_ro();
2450 1071e028 Scott Ullrich
}
2451
2452 431484c8 Ryan Wagoner
function upnp_action ($action) {
2453 aa6798c0 Scott Ullrich
	global $g, $config;
2454 61e047a5 Phil Davis
	switch ($action) {
2455 431484c8 Ryan Wagoner
		case "start":
2456 c1ac2424 Ermal
			if (file_exists('/var/etc/miniupnpd.conf')) {
2457
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
2458
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
2459
			}
2460 431484c8 Ryan Wagoner
			break;
2461
		case "stop":
2462 c1ac2424 Ermal
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
2463 61e047a5 Phil Davis
			while ((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0) {
2464 73239086 Seth Mos
				mwexec('killall miniupnpd 2>/dev/null', true);
2465 61e047a5 Phil Davis
			}
2466 431484c8 Ryan Wagoner
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
2467
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
2468
			break;
2469
		case "restart":
2470
			upnp_action('stop');
2471
			upnp_action('start');
2472
			break;
2473
	}
2474
}
2475
2476 6f20377b Scott Ullrich
function upnp_start() {
2477 dcc897e5 Ermal
	global $config;
2478 0c331f1e Ermal Lu?i
2479 61e047a5 Phil Davis
	if (!isset($config['installedpackages']['miniupnpd']['config'])) {
2480 0c331f1e Ermal Lu?i
		return;
2481 61e047a5 Phil Davis
	}
2482 0c331f1e Ermal Lu?i
2483 61e047a5 Phil Davis
	if ($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2484 54bdff75 Vinicius Coque
		echo gettext("Starting UPnP service... ");
2485 dcc897e5 Ermal
		require_once('/usr/local/pkg/miniupnpd.inc');
2486
		sync_package_miniupnpd();
2487
		echo "done.\n";
2488 6f20377b Scott Ullrich
	}
2489
}
2490
2491 6c07db48 Phil Davis
function install_cron_job($command, $active = false, $minute = "0", $hour = "*", $monthday = "*", $month = "*", $weekday = "*", $who = "root") {
2492 85405c11 jim-p
	global $config, $g;
2493
2494
	$is_installed = false;
2495 994a0644 Phil Davis
	$cron_changed = true;
2496 85405c11 jim-p
2497 61e047a5 Phil Davis
	if (!is_array($config['cron'])) {
2498 c2d97111 Ermal
		$config['cron'] = array();
2499 61e047a5 Phil Davis
	}
2500
	if (!is_array($config['cron']['item'])) {
2501 c2d97111 Ermal
		$config['cron']['item'] = array();
2502 61e047a5 Phil Davis
	}
2503 85405c11 jim-p
2504 6c07db48 Phil Davis
	$x = 0;
2505 61e047a5 Phil Davis
	foreach ($config['cron']['item'] as $item) {
2506
		if (strstr($item['command'], $command)) {
2507 85405c11 jim-p
			$is_installed = true;
2508
			break;
2509
		}
2510
		$x++;
2511
	}
2512
2513 61e047a5 Phil Davis
	if ($active) {
2514 85405c11 jim-p
		$cron_item = array();
2515
		$cron_item['minute'] = $minute;
2516
		$cron_item['hour'] = $hour;
2517
		$cron_item['mday'] = $monthday;
2518
		$cron_item['month'] = $month;
2519
		$cron_item['wday'] = $weekday;
2520
		$cron_item['who'] = $who;
2521
		$cron_item['command'] = $command;
2522 61e047a5 Phil Davis
		if (!$is_installed) {
2523 85405c11 jim-p
			$config['cron']['item'][] = $cron_item;
2524 f1a44a3a Carlos Eduardo Ramos
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
2525 85405c11 jim-p
		} else {
2526 aff83787 Phil Davis
			if ($config['cron']['item'][$x] == $cron_item) {
2527 994a0644 Phil Davis
				$cron_changed = false;
2528
				log_error(sprintf(gettext("Checked cron job for %s, no change needed"), $command));
2529
			} else {
2530
				$config['cron']['item'][$x] = $cron_item;
2531
				write_config(sprintf(gettext("Updated cron job for %s"), $command));
2532
			}
2533 85405c11 jim-p
		}
2534
	} else {
2535 61e047a5 Phil Davis
		if ($is_installed == true) {
2536 85405c11 jim-p
			unset($config['cron']['item'][$x]);
2537 149ed85e bcyrill
			write_config(sprintf(gettext("Removed cron job for %s"), $command));
2538 85405c11 jim-p
		}
2539
	}
2540 994a0644 Phil Davis
2541 61e047a5 Phil Davis
	if ($cron_changed) {
2542 994a0644 Phil Davis
		configure_cron();
2543 61e047a5 Phil Davis
	}
2544 85405c11 jim-p
}
2545
2546 693833cb Seth Mos
?>