Project

General

Profile

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