Project

General

Profile

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