Project

General

Profile

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