Project

General

Profile

Download (48.8 KB) Statistics
| Branch: | Tag: | Revision:
1 e9f147c8 Scott Ullrich
<?php
2 5b237745 Scott Ullrich
/*
3
	services_dhcp.php
4
*/
5 b5f6e690 Stephen Beaver
/* ====================================================================
6
 *	Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved.
7 919d91f9 Phil Davis
 *
8 cb41dd63 Renato Botelho
 *	Some or all of this file is based on the m0n0wall project which is
9
 *	Copyright (c)  2004 Manuel Kasper (BSD 2 clause)
10 b5f6e690 Stephen Beaver
 *
11
 *	Redistribution and use in source and binary forms, with or without modification,
12
 *	are permitted provided that the following conditions are met:
13
 *
14
 *	1. Redistributions of source code must retain the above copyright notice,
15
 *		this list of conditions and the following disclaimer.
16
 *
17
 *	2. Redistributions in binary form must reproduce the above copyright
18
 *		notice, this list of conditions and the following disclaimer in
19
 *		the documentation and/or other materials provided with the
20
 *		distribution.
21
 *
22
 *	3. All advertising materials mentioning features or use of this software
23
 *		must display the following acknowledgment:
24
 *		"This product includes software developed by the pfSense Project
25
 *		 for use in the pfSense software distribution. (http://www.pfsense.org/).
26
 *
27
 *	4. The names "pfSense" and "pfSense Project" must not be used to
28
 *		 endorse or promote products derived from this software without
29
 *		 prior written permission. For written permission, please contact
30
 *		 coreteam@pfsense.org.
31
 *
32
 *	5. Products derived from this software may not be called "pfSense"
33
 *		nor may "pfSense" appear in their names without prior written
34
 *		permission of the Electric Sheep Fencing, LLC.
35
 *
36
 *	6. Redistributions of any form whatsoever must retain the following
37
 *		acknowledgment:
38
 *
39
 *	"This product includes software developed by the pfSense Project
40
 *	for use in the pfSense software distribution (http://www.pfsense.org/).
41
 *
42
 *	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
43
 *	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44
 *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
45
 *	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
46
 *	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47
 *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48
 *	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50
 *	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
51
 *	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52
 *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
53
 *	OF THE POSSIBILITY OF SUCH DAMAGE.
54
 *
55
 *	====================================================================
56
 *
57
 */
58 5b237745 Scott Ullrich
59 6b07c15a Matthew Grooms
##|+PRIV
60
##|*IDENT=page-services-dhcpserver
61 9599211d jim-p
##|*NAME=Services: DHCP Server
62
##|*DESCR=Allow access to the 'Services: DHCP Server' page.
63 6b07c15a Matthew Grooms
##|*MATCH=services_dhcp.php*
64
##|-PRIV
65
66 b7597d4e Bill Marquette
require("guiconfig.inc");
67 6c124212 Phil Davis
require_once("filter.inc");
68 6303601e heper
require_once('rrd.inc');
69
require_once("shaper.inc");
70 5b237745 Scott Ullrich
71 8f8682f7 Phil Davis
if (!$g['services_dhcp_server_enable']) {
72 6f3d2063 Renato Botelho
	header("Location: /");
73 2ee0410f Scott Ullrich
	exit;
74
}
75
76 5b237745 Scott Ullrich
$if = $_GET['if'];
77 8f8682f7 Phil Davis
if (!empty($_POST['if'])) {
78 5b237745 Scott Ullrich
	$if = $_POST['if'];
79 8f8682f7 Phil Davis
}
80 e9f147c8 Scott Ullrich
81 11bc553c Scott Ullrich
/* if OLSRD is enabled, allow WAN to house DHCP. */
82 8f8682f7 Phil Davis
if ($config['installedpackages']['olsrd']) {
83
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
84
		if ($olsrd['enable']) {
85
			$is_olsr_enabled = true;
86
			break;
87
		}
88 a3b466b5 Scott Ullrich
	}
89 8f8682f7 Phil Davis
}
90 5b237745 Scott Ullrich
91 934240ef Ermal Luçi
$iflist = get_configured_interface_with_descr();
92 5b237745 Scott Ullrich
93 1c451b06 Scott Ullrich
/* set the starting interface */
94 f19651d1 Ermal
if (!$if || !isset($iflist[$if])) {
95 01fdb2d3 Erik Fonnesbeck
	foreach ($iflist as $ifent => $ifname) {
96 de792e62 jim-p
		$oc = $config['interfaces'][$ifent];
97 e5770bc2 Bill Marquette
		if ((is_array($config['dhcpd'][$ifent]) && !isset($config['dhcpd'][$ifent]['enable']) && (!is_ipaddrv4($oc['ipaddr']))) ||
98 6e3488e9 Phil Davis
		    (!is_array($config['dhcpd'][$ifent]) && (!is_ipaddrv4($oc['ipaddr'])))) {
99 01fdb2d3 Erik Fonnesbeck
			continue;
100 8f8682f7 Phil Davis
		}
101 b5f6e690 Stephen Beaver
102 01fdb2d3 Erik Fonnesbeck
		$if = $ifent;
103
		break;
104
	}
105 f19651d1 Ermal
}
106 0a2c6a5b Scott Ullrich
107 cba980f6 jim-p
$act = $_GET['act'];
108 8f8682f7 Phil Davis
if (!empty($_POST['act'])) {
109 cba980f6 jim-p
	$act = $_POST['act'];
110 8f8682f7 Phil Davis
}
111 cba980f6 jim-p
112 cc6052f0 Renato Botelho
$a_pools = array();
113 cba980f6 jim-p
114 8f8682f7 Phil Davis
if (is_array($config['dhcpd'][$if])) {
115 cba980f6 jim-p
	$pool = $_GET['pool'];
116 8f8682f7 Phil Davis
	if (is_numeric($_POST['pool'])) {
117 cba980f6 jim-p
		$pool = $_POST['pool'];
118 8f8682f7 Phil Davis
	}
119 cba980f6 jim-p
120
	// If we have a pool but no interface name, that's not valid. Redirect away.
121
	if (is_numeric($pool) && empty($if)) {
122
		header("Location: services_dhcp.php");
123
		exit;
124 de792e62 jim-p
	}
125 cba980f6 jim-p
126 8f8682f7 Phil Davis
	if (!is_array($config['dhcpd'][$if]['pool'])) {
127 cba980f6 jim-p
		$config['dhcpd'][$if]['pool'] = array();
128 8f8682f7 Phil Davis
	}
129 b5f6e690 Stephen Beaver
130 cba980f6 jim-p
	$a_pools = &$config['dhcpd'][$if]['pool'];
131
132 8f8682f7 Phil Davis
	if (is_numeric($pool) && $a_pools[$pool]) {
133 cba980f6 jim-p
		$dhcpdconf = &$a_pools[$pool];
134 8f8682f7 Phil Davis
	} elseif ($act == "newpool") {
135 cba980f6 jim-p
		$dhcpdconf = array();
136 8f8682f7 Phil Davis
	} else {
137 cba980f6 jim-p
		$dhcpdconf = &$config['dhcpd'][$if];
138 8f8682f7 Phil Davis
	}
139 cba980f6 jim-p
}
140
if (is_array($dhcpdconf)) {
141
	// Global Options
142
	if (!is_numeric($pool) && !($act == "newpool")) {
143
		$pconfig['enable'] = isset($dhcpdconf['enable']);
144
		$pconfig['staticarp'] = isset($dhcpdconf['staticarp']);
145
		// No reason to specify this per-pool, per the dhcpd.conf man page it needs to be in every
146 b5f6e690 Stephen Beaver
		//	 pool and should be specified in every pool both nodes share, so we'll treat it as global
147 cba980f6 jim-p
		$pconfig['failover_peerip'] = $dhcpdconf['failover_peerip'];
148 466aae83 Phil Davis
149
		// dhcpleaseinlocaltime is global to all interfaces. So if it is selected on any interface,
150
		// then show it true/checked.
151
		foreach ($config['dhcpd'] as $dhcpdifitem) {
152
			$dhcpleaseinlocaltime = $dhcpdifitem['dhcpleaseinlocaltime'];
153 8f8682f7 Phil Davis
			if ($dhcpleaseinlocaltime) {
154 466aae83 Phil Davis
				break;
155 8f8682f7 Phil Davis
			}
156 466aae83 Phil Davis
		}
157
158
		$pconfig['dhcpleaseinlocaltime'] = $dhcpleaseinlocaltime;
159
160 8f8682f7 Phil Davis
		if (!is_array($dhcpdconf['staticmap'])) {
161 cba980f6 jim-p
			$dhcpdconf['staticmap'] = array();
162 8f8682f7 Phil Davis
		}
163 b5f6e690 Stephen Beaver
164 cba980f6 jim-p
		$a_maps = &$dhcpdconf['staticmap'];
165 ee1fb205 jim-p
	} else {
166
		// Options that exist only in pools
167
		$pconfig['descr'] = $dhcpdconf['descr'];
168 cba980f6 jim-p
	}
169
170
	// Options that can be global or per-pool.
171
	if (is_array($dhcpdconf['range'])) {
172
		$pconfig['range_from'] = $dhcpdconf['range']['from'];
173
		$pconfig['range_to'] = $dhcpdconf['range']['to'];
174
	}
175 b5f6e690 Stephen Beaver
176 cba980f6 jim-p
	$pconfig['deftime'] = $dhcpdconf['defaultleasetime'];
177
	$pconfig['maxtime'] = $dhcpdconf['maxleasetime'];
178
	$pconfig['gateway'] = $dhcpdconf['gateway'];
179
	$pconfig['domain'] = $dhcpdconf['domain'];
180
	$pconfig['domainsearchlist'] = $dhcpdconf['domainsearchlist'];
181 8f8682f7 Phil Davis
	list($pconfig['wins1'], $pconfig['wins2']) = $dhcpdconf['winsserver'];
182
	list($pconfig['dns1'], $pconfig['dns2'], $pconfig['dns3'], $pconfig['dns4']) = $dhcpdconf['dnsserver'];
183 cba980f6 jim-p
	$pconfig['denyunknown'] = isset($dhcpdconf['denyunknown']);
184
	$pconfig['ddnsdomain'] = $dhcpdconf['ddnsdomain'];
185 87019fc4 Andres Petralli
	$pconfig['ddnsdomainprimary'] = $dhcpdconf['ddnsdomainprimary'];
186
	$pconfig['ddnsdomainkeyname'] = $dhcpdconf['ddnsdomainkeyname'];
187
	$pconfig['ddnsdomainkey'] = $dhcpdconf['ddnsdomainkey'];
188 cba980f6 jim-p
	$pconfig['ddnsupdate'] = isset($dhcpdconf['ddnsupdate']);
189
	$pconfig['mac_allow'] = $dhcpdconf['mac_allow'];
190
	$pconfig['mac_deny'] = $dhcpdconf['mac_deny'];
191 8f8682f7 Phil Davis
	list($pconfig['ntp1'], $pconfig['ntp2']) = $dhcpdconf['ntpserver'];
192 cba980f6 jim-p
	$pconfig['tftp'] = $dhcpdconf['tftp'];
193
	$pconfig['ldap'] = $dhcpdconf['ldap'];
194
	$pconfig['netboot'] = isset($dhcpdconf['netboot']);
195
	$pconfig['nextserver'] = $dhcpdconf['nextserver'];
196
	$pconfig['filename'] = $dhcpdconf['filename'];
197 7023c602 Charlie Root
	$pconfig['filename32'] = $dhcpdconf['filename32'];
198
	$pconfig['filename64'] = $dhcpdconf['filename64'];
199 cba980f6 jim-p
	$pconfig['rootpath'] = $dhcpdconf['rootpath'];
200
	$pconfig['netmask'] = $dhcpdconf['netmask'];
201
	$pconfig['numberoptions'] = $dhcpdconf['numberoptions'];
202 18d316a5 heper
	$pconfig['statsgraph'] = $dhcpdconf['statsgraph'];
203 89019922 Ermal Luçi
}
204 31c59d0d Scott Ullrich
205 51cd7a1e Evgeny Yurchenko
$ifcfgip = $config['interfaces'][$if]['ipaddr'];
206
$ifcfgsn = $config['interfaces'][$if]['subnet'];
207 5b237745 Scott Ullrich
208 1f1a08c8 jim-p
function validate_partial_mac_list($maclist) {
209
	$macs = explode(',', $maclist);
210
211
	// Loop through and look for invalid MACs.
212 8f8682f7 Phil Davis
	foreach ($macs as $mac) {
213
		if (!is_macaddr($mac, true)) {
214 1f1a08c8 jim-p
			return false;
215 8f8682f7 Phil Davis
		}
216
	}
217 b5f6e690 Stephen Beaver
218 1f1a08c8 jim-p
	return true;
219
}
220
221 565488c9 Renato Botelho
if (isset($_POST['submit'])) {
222 5b237745 Scott Ullrich
223
	unset($input_errors);
224 b7597d4e Bill Marquette
225 5b237745 Scott Ullrich
	$pconfig = $_POST;
226
227 6d1af0e9 jim-p
	$numberoptions = array();
228 6c07db48 Phil Davis
	for ($x = 0; $x < 99; $x++) {
229 8f8682f7 Phil Davis
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
230 6d1af0e9 jim-p
			$numbervalue = array();
231
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
232 678dfd0f Erik Fonnesbeck
			$numbervalue['type'] = htmlspecialchars($_POST["itemtype{$x}"]);
233
			$numbervalue['value'] = str_replace('&quot;', '"', htmlspecialchars($_POST["value{$x}"]));
234 6d1af0e9 jim-p
			$numberoptions['item'][] = $numbervalue;
235
		}
236
	}
237 b5f6e690 Stephen Beaver
238 466aae83 Phil Davis
	// Reload the new pconfig variable that the form uses.
239 6d1af0e9 jim-p
	$pconfig['numberoptions'] = $numberoptions;
240
241 5b237745 Scott Ullrich
	/* input validation */
242 cba980f6 jim-p
	if ($_POST['enable'] || is_numeric($pool) || $act == "newpool") {
243 5b237745 Scott Ullrich
		$reqdfields = explode(" ", "range_from range_to");
244 8f8682f7 Phil Davis
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
245 e9f147c8 Scott Ullrich
246 507628d5 Renato Botelho
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
247 de792e62 jim-p
248 8f8682f7 Phil Davis
		if (($_POST['range_from'] && !is_ipaddrv4($_POST['range_from']))) {
249 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid range must be specified.");
250 8f8682f7 Phil Davis
		}
251
		if (($_POST['range_to'] && !is_ipaddrv4($_POST['range_to']))) {
252 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid range must be specified.");
253 8f8682f7 Phil Davis
		}
254
		if (($_POST['gateway'] && $_POST['gateway'] != "none" && !is_ipaddrv4($_POST['gateway']))) {
255 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the gateway.");
256 8f8682f7 Phil Davis
		}
257
		if (($_POST['wins1'] && !is_ipaddrv4($_POST['wins1'])) || ($_POST['wins2'] && !is_ipaddrv4($_POST['wins2']))) {
258 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the primary/secondary WINS servers.");
259 8f8682f7 Phil Davis
		}
260 9bc59815 Evgeny Yurchenko
		$parent_ip = get_interface_ip($_POST['if']);
261 1bd021e3 timdufrane
		if (is_ipaddrv4($parent_ip) && $_POST['gateway'] && $_POST['gateway'] != "none") {
262 9bc59815 Evgeny Yurchenko
			$parent_sn = get_interface_subnet($_POST['if']);
263 8f8682f7 Phil Davis
			if (!ip_in_subnet($_POST['gateway'], gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn) && !ip_in_interface_alias_subnet($_POST['if'], $_POST['gateway'])) {
264 9bc59815 Evgeny Yurchenko
				$input_errors[] = sprintf(gettext("The gateway address %s does not lie within the chosen interface's subnet."), $_POST['gateway']);
265 8f8682f7 Phil Davis
			}
266 45d1024d Scott Ullrich
		}
267 b5f6e690 Stephen Beaver
268 8f8682f7 Phil Davis
		if (($_POST['dns1'] && !is_ipaddrv4($_POST['dns1'])) || ($_POST['dns2'] && !is_ipaddrv4($_POST['dns2'])) || ($_POST['dns3'] && !is_ipaddrv4($_POST['dns3'])) || ($_POST['dns4'] && !is_ipaddrv4($_POST['dns4']))) {
269 3b5707db Phil Davis
			$input_errors[] = gettext("A valid IP address must be specified for each of the DNS servers.");
270 8f8682f7 Phil Davis
		}
271 26e3ca70 sullrich
272 8f8682f7 Phil Davis
		if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
273
			$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
274
		}
275 e680b2f9 Renato Botelho
276
		if (isset($config['captiveportal']) && is_array($config['captiveportal'])) {
277
			$deftime = 7200; // Default value if it's empty
278 8f8682f7 Phil Davis
			if (is_numeric($_POST['deftime'])) {
279 e680b2f9 Renato Botelho
				$deftime = $_POST['deftime'];
280 8f8682f7 Phil Davis
			}
281 e680b2f9 Renato Botelho
282
			foreach ($config['captiveportal'] as $cpZone => $cpdata) {
283 8f8682f7 Phil Davis
				if (!isset($cpdata['enable'])) {
284 e680b2f9 Renato Botelho
					continue;
285 8f8682f7 Phil Davis
				}
286
				if (!isset($cpdata['timeout']) || !is_numeric($cpdata['timeout'])) {
287 e680b2f9 Renato Botelho
					continue;
288 8f8682f7 Phil Davis
				}
289 e680b2f9 Renato Botelho
				$cp_ifs = explode(',', $cpdata['interface']);
290 8f8682f7 Phil Davis
				if (!in_array($if, $cp_ifs)) {
291 e680b2f9 Renato Botelho
					continue;
292 8f8682f7 Phil Davis
				}
293
				if ($cpdata['timeout'] > $deftime) {
294 e680b2f9 Renato Botelho
					$input_errors[] = sprintf(gettext(
295
						"The Captive Portal zone '%s' has Hard Timeout parameter set to a value bigger than Default lease time (%s)."), $cpZone, $deftime);
296 8f8682f7 Phil Davis
				}
297 e680b2f9 Renato Botelho
			}
298
		}
299
300 8f8682f7 Phil Davis
		if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
301 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
302 8f8682f7 Phil Davis
		}
303
		if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain']))) {
304 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
305 8f8682f7 Phil Davis
		}
306
		if (($_POST['ddnsdomain'] && !is_ipaddrv4($_POST['ddnsdomainprimary']))) {
307 87019fc4 Andres Petralli
			$input_errors[] = gettext("A valid primary domain name server IP address must be specified for the dynamic domain name.");
308 8f8682f7 Phil Davis
		}
309 87019fc4 Andres Petralli
		if (($_POST['ddnsdomainkey'] && !$_POST['ddnsdomainkeyname']) ||
310 6e3488e9 Phil Davis
		    ($_POST['ddnsdomainkeyname'] && !$_POST['ddnsdomainkey'])) {
311 87019fc4 Andres Petralli
			$input_errors[] = gettext("You must specify both a valid domain key and key name.");
312 8f8682f7 Phil Davis
		}
313 42a3cbab Pierre POMES
		if ($_POST['domainsearchlist']) {
314 8f8682f7 Phil Davis
			$domain_array = preg_split("/[ ;]+/", $_POST['domainsearchlist']);
315 42a3cbab Pierre POMES
			foreach ($domain_array as $curdomain) {
316
				if (!is_domain($curdomain)) {
317
					$input_errors[] = gettext("A valid domain search list must be specified.");
318
					break;
319
				}
320
			}
321
		}
322 1f1a08c8 jim-p
323
		// Validate MACs
324 8f8682f7 Phil Davis
		if (!empty($_POST['mac_allow']) && !validate_partial_mac_list($_POST['mac_allow'])) {
325 1f1a08c8 jim-p
			$input_errors[] = gettext("If you specify a mac allow list, it must contain only valid partial MAC addresses.");
326 8f8682f7 Phil Davis
		}
327
		if (!empty($_POST['mac_deny']) && !validate_partial_mac_list($_POST['mac_deny'])) {
328 1f1a08c8 jim-p
			$input_errors[] = gettext("If you specify a mac deny list, it must contain only valid partial MAC addresses.");
329 8f8682f7 Phil Davis
		}
330 1f1a08c8 jim-p
331 8f8682f7 Phil Davis
		if (($_POST['ntp1'] && !is_ipaddrv4($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv4($_POST['ntp2']))) {
332 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the primary/secondary NTP servers.");
333 8f8682f7 Phil Davis
		}
334
		if (($_POST['domain'] && !is_domain($_POST['domain']))) {
335 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
336 8f8682f7 Phil Davis
		}
337
		if ($_POST['tftp'] && !is_ipaddrv4($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
338 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address or hostname must be specified for the TFTP server.");
339 8f8682f7 Phil Davis
		}
340
		if (($_POST['nextserver'] && !is_ipaddrv4($_POST['nextserver']))) {
341 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the network boot server.");
342 8f8682f7 Phil Davis
		}
343 2c75b451 sullrich
344 8f8682f7 Phil Davis
		if (gen_subnet($ifcfgip, $ifcfgsn) == $_POST['range_from']) {
345 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("You cannot use the network address in the starting subnet range.");
346 8f8682f7 Phil Davis
		}
347
		if (gen_subnet_max($ifcfgip, $ifcfgsn) == $_POST['range_to']) {
348 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("You cannot use the broadcast address in the ending subnet range.");
349 8f8682f7 Phil Davis
		}
350 e9f147c8 Scott Ullrich
351 2c75b451 sullrich
		// Disallow a range that includes the virtualip
352 7dfa60fa Ermal Lu?i
		if (is_array($config['virtualip']['vip'])) {
353 8f8682f7 Phil Davis
			foreach ($config['virtualip']['vip'] as $vip) {
354
				if ($vip['interface'] == $if) {
355
					if ($vip['subnet'] && is_inrange_v4($vip['subnet'], $_POST['range_from'], $_POST['range_to'])) {
356
						$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IP address %s."), $vip['subnet']);
357
					}
358
				}
359 7dfa60fa Ermal Lu?i
			}
360 2c75b451 sullrich
		}
361
362 073a2697 jim-p
		$noip = false;
363 8f8682f7 Phil Davis
		if (is_array($a_maps)) {
364
			foreach ($a_maps as $map) {
365
				if (empty($map['ipaddr'])) {
366 2c7497cb Scott Ullrich
					$noip = true;
367 8f8682f7 Phil Davis
				}
368
			}
369
		}
370 b5f6e690 Stephen Beaver
371 8f8682f7 Phil Davis
		if ($_POST['staticarp'] && $noip) {
372 073a2697 jim-p
			$input_errors[] = "Cannot enable static ARP when you have static map entries without IP addresses. Ensure all static maps have IP addresses and try again.";
373 8f8682f7 Phil Davis
		}
374 073a2697 jim-p
375 8f8682f7 Phil Davis
		if (is_array($pconfig['numberoptions']['item'])) {
376 678dfd0f Erik Fonnesbeck
			foreach ($pconfig['numberoptions']['item'] as $numberoption) {
377 8f8682f7 Phil Davis
				if ($numberoption['type'] == 'text' && strstr($numberoption['value'], '"')) {
378 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Text type cannot include quotation marks.");
379 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'string' && !preg_match('/^"[^"]*"$/', $numberoption['value']) && !preg_match('/^[0-9a-f]{2}(?:\:[0-9a-f]{2})*$/i', $numberoption['value'])) {
380 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("String type must be enclosed in quotes like \"this\" or must be a series of octets specified in hexadecimal, separated by colons, like 01:23:45:67:89:ab:cd:ef");
381 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'boolean' && $numberoption['value'] != 'true' && $numberoption['value'] != 'false' && $numberoption['value'] != 'on' && $numberoption['value'] != 'off') {
382 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Boolean type must be true, false, on, or off.");
383 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'unsigned integer 8' && (!is_numeric($numberoption['value']) || $numberoption['value'] < 0 || $numberoption['value'] > 255)) {
384 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Unsigned 8-bit integer type must be a number in the range 0 to 255.");
385 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'unsigned integer 16' && (!is_numeric($numberoption['value']) || $numberoption['value'] < 0 || $numberoption['value'] > 65535)) {
386 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Unsigned 16-bit integer type must be a number in the range 0 to 65535.");
387 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'unsigned integer 32' && (!is_numeric($numberoption['value']) || $numberoption['value'] < 0 || $numberoption['value'] > 4294967295)) {
388 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Unsigned 32-bit integer type must be a number in the range 0 to 4294967295.");
389 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'signed integer 8' && (!is_numeric($numberoption['value']) || $numberoption['value'] < -128 || $numberoption['value'] > 127)) {
390 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Signed 8-bit integer type must be a number in the range -128 to 127.");
391 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'signed integer 16' && (!is_numeric($numberoption['value']) || $numberoption['value'] < -32768 || $numberoption['value'] > 32767)) {
392 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Signed 16-bit integer type must be a number in the range -32768 to 32767.");
393 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'signed integer 32' && (!is_numeric($numberoption['value']) || $numberoption['value'] < -2147483648 || $numberoption['value'] > 2147483647)) {
394 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Signed 32-bit integer type must be a number in the range -2147483648 to 2147483647.");
395 8f8682f7 Phil Davis
				} else if ($numberoption['type'] == 'ip-address' && !is_ipaddrv4($numberoption['value']) && !is_hostname($numberoption['value'])) {
396 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("IP address or host type must be an IP address or host name.");
397 8f8682f7 Phil Davis
				}
398 678dfd0f Erik Fonnesbeck
			}
399
		}
400
401 5b237745 Scott Ullrich
		if (!$input_errors) {
402
			/* make sure the range lies within the current subnet */
403 96033063 Erik Fonnesbeck
			$subnet_start = ip2ulong(long2ip32(ip2long($ifcfgip) & gen_subnet_mask_long($ifcfgsn)));
404
			$subnet_end = ip2ulong(long2ip32(ip2long($ifcfgip) | (~gen_subnet_mask_long($ifcfgsn))));
405 e9f147c8 Scott Ullrich
406 96033063 Erik Fonnesbeck
			if ((ip2ulong($_POST['range_from']) < $subnet_start) || (ip2ulong($_POST['range_from']) > $subnet_end) ||
407 6e3488e9 Phil Davis
			    (ip2ulong($_POST['range_to']) < $subnet_start) || (ip2ulong($_POST['range_to']) > $subnet_end)) {
408 40ad67e0 Rafael Lucas
				$input_errors[] = gettext("The specified range lies outside of the current subnet.");
409 5b237745 Scott Ullrich
			}
410 e9f147c8 Scott Ullrich
411 8f8682f7 Phil Davis
			if (ip2ulong($_POST['range_from']) > ip2ulong($_POST['range_to'])) {
412 40ad67e0 Rafael Lucas
				$input_errors[] = gettext("The range is invalid (first element higher than second element).");
413 8f8682f7 Phil Davis
			}
414 e9f147c8 Scott Ullrich
415 f657f5e1 Renato Botelho
			if (is_numeric($pool) || ($act == "newpool")) {
416
				$rfrom = $config['dhcpd'][$if]['range']['from'];
417
				$rto = $config['dhcpd'][$if]['range']['to'];
418
419 8f8682f7 Phil Davis
				if (is_inrange_v4($_POST['range_from'], $rfrom, $rto) || is_inrange_v4($_POST['range_to'], $rfrom, $rto)) {
420 f657f5e1 Renato Botelho
					$input_errors[] = gettext("The specified range must not be within the DHCP range for this interface.");
421 8f8682f7 Phil Davis
				}
422 f657f5e1 Renato Botelho
			}
423
424
			foreach ($a_pools as $id => $p) {
425 8f8682f7 Phil Davis
				if (is_numeric($pool) && ($id == $pool)) {
426 f657f5e1 Renato Botelho
					continue;
427 8f8682f7 Phil Davis
				}
428 f657f5e1 Renato Botelho
429
				if (is_inrange_v4($_POST['range_from'], $p['range']['from'], $p['range']['to']) ||
430 6e3488e9 Phil Davis
				    is_inrange_v4($_POST['range_to'], $p['range']['from'], $p['range']['to'])) {
431 f657f5e1 Renato Botelho
					$input_errors[] = gettext("The specified range must not be within the range configured on a DHCP pool for this interface.");
432
					break;
433
				}
434
			}
435 cba980f6 jim-p
436 5b237745 Scott Ullrich
			/* make sure that the DHCP Relay isn't enabled on this interface */
437 8f8682f7 Phil Davis
			if (isset($config['dhcrelay']['enable']) && (stristr($config['dhcrelay']['interface'], $if) !== false)) {
438
				$input_errors[] = sprintf(gettext("You must disable the DHCP relay on the %s interface before enabling the DHCP server."), $iflist[$if]);
439
			}
440 630d7025 jim-p
441
			$dynsubnet_start = ip2ulong($_POST['range_from']);
442
			$dynsubnet_end = ip2ulong($_POST['range_to']);
443 f02f0675 Erik Fonnesbeck
			if (is_array($a_maps)) {
444
				foreach ($a_maps as $map) {
445 8f8682f7 Phil Davis
					if (empty($map['ipaddr'])) {
446 f02f0675 Erik Fonnesbeck
						continue;
447 8f8682f7 Phil Davis
					}
448 f02f0675 Erik Fonnesbeck
					if ((ip2ulong($map['ipaddr']) > $dynsubnet_start) &&
449 6e3488e9 Phil Davis
					    (ip2ulong($map['ipaddr']) < $dynsubnet_end)) {
450 f02f0675 Erik Fonnesbeck
						$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
451
						break;
452
					}
453 630d7025 jim-p
				}
454
			}
455 5b237745 Scott Ullrich
		}
456
	}
457
458
	if (!$input_errors) {
459 cba980f6 jim-p
		if (!is_numeric($pool)) {
460
			if ($act == "newpool") {
461
				$dhcpdconf = array();
462
			} else {
463 8f8682f7 Phil Davis
				if (!is_array($config['dhcpd'][$if])) {
464 cba980f6 jim-p
					$config['dhcpd'][$if] = array();
465 8f8682f7 Phil Davis
				}
466 cba980f6 jim-p
				$dhcpdconf = $config['dhcpd'][$if];
467
			}
468
		} else {
469
			if (is_array($a_pools[$pool])) {
470
				$dhcpdconf = $a_pools[$pool];
471
			} else {
472
				// Someone specified a pool but it doesn't exist. Punt.
473
				header("Location: services_dhcp.php");
474
				exit;
475
			}
476
		}
477 8f8682f7 Phil Davis
		if (!is_array($dhcpdconf['range'])) {
478 cba980f6 jim-p
			$dhcpdconf['range'] = array();
479 8f8682f7 Phil Davis
		}
480 cba980f6 jim-p
481 6c124212 Phil Davis
		$dhcpd_enable_changed = false;
482
483 cba980f6 jim-p
		// Global Options
484
		if (!is_numeric($pool) && !($act == "newpool")) {
485 6c124212 Phil Davis
			$old_dhcpd_enable = isset($dhcpdconf['enable']);
486
			$new_dhcpd_enable = ($_POST['enable']) ? true : false;
487
			if ($old_dhcpd_enable != $new_dhcpd_enable) {
488
				/* DHCP has been enabled or disabled. The pf ruleset will need to be rebuilt to allow or disallow DHCP. */
489
				$dhcpd_enable_changed = true;
490
			}
491 b5f6e690 Stephen Beaver
492 6c124212 Phil Davis
			$dhcpdconf['enable'] = $new_dhcpd_enable;
493 cba980f6 jim-p
			$dhcpdconf['staticarp'] = ($_POST['staticarp']) ? true : false;
494
			$previous = $dhcpdconf['failover_peerip'];
495 b5f6e690 Stephen Beaver
			if ($previous != $_POST['failover_peerip']) {
496 cba980f6 jim-p
				mwexec("/bin/rm -rf /var/dhcpd/var/db/*");
497 8f8682f7 Phil Davis
			}
498 b5f6e690 Stephen Beaver
499 cba980f6 jim-p
			$dhcpdconf['failover_peerip'] = $_POST['failover_peerip'];
500 466aae83 Phil Davis
			// dhcpleaseinlocaltime is global to all interfaces. So update the setting on all interfaces.
501
			foreach ($config['dhcpd'] as &$dhcpdifitem) {
502
				$dhcpdifitem['dhcpleaseinlocaltime'] = $_POST['dhcpleaseinlocaltime'];
503
			}
504 ee1fb205 jim-p
		} else {
505
			// Options that exist only in pools
506
			$dhcpdconf['descr'] = $_POST['descr'];
507 cba980f6 jim-p
		}
508
509
		// Options that can be global or per-pool.
510
		$dhcpdconf['range']['from'] = $_POST['range_from'];
511
		$dhcpdconf['range']['to'] = $_POST['range_to'];
512
		$dhcpdconf['defaultleasetime'] = $_POST['deftime'];
513
		$dhcpdconf['maxleasetime'] = $_POST['maxtime'];
514
		$dhcpdconf['netmask'] = $_POST['netmask'];
515
516
		unset($dhcpdconf['winsserver']);
517 8f8682f7 Phil Davis
		if ($_POST['wins1']) {
518 cba980f6 jim-p
			$dhcpdconf['winsserver'][] = $_POST['wins1'];
519 8f8682f7 Phil Davis
		}
520
		if ($_POST['wins2']) {
521 cba980f6 jim-p
			$dhcpdconf['winsserver'][] = $_POST['wins2'];
522 8f8682f7 Phil Davis
		}
523 4cab31d0 Scott Ullrich
524 cba980f6 jim-p
		unset($dhcpdconf['dnsserver']);
525 8f8682f7 Phil Davis
		if ($_POST['dns1']) {
526 cba980f6 jim-p
			$dhcpdconf['dnsserver'][] = $_POST['dns1'];
527 8f8682f7 Phil Davis
		}
528
		if ($_POST['dns2']) {
529 cba980f6 jim-p
			$dhcpdconf['dnsserver'][] = $_POST['dns2'];
530 8f8682f7 Phil Davis
		}
531
		if ($_POST['dns3']) {
532 3b5707db Phil Davis
			$dhcpdconf['dnsserver'][] = $_POST['dns3'];
533 8f8682f7 Phil Davis
		}
534
		if ($_POST['dns4']) {
535 3b5707db Phil Davis
			$dhcpdconf['dnsserver'][] = $_POST['dns4'];
536 8f8682f7 Phil Davis
		}
537 cba980f6 jim-p
538
		$dhcpdconf['gateway'] = $_POST['gateway'];
539
		$dhcpdconf['domain'] = $_POST['domain'];
540
		$dhcpdconf['domainsearchlist'] = $_POST['domainsearchlist'];
541
		$dhcpdconf['denyunknown'] = ($_POST['denyunknown']) ? true : false;
542
		$dhcpdconf['ddnsdomain'] = $_POST['ddnsdomain'];
543 87019fc4 Andres Petralli
		$dhcpdconf['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
544
		$dhcpdconf['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
545
		$dhcpdconf['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
546 cba980f6 jim-p
		$dhcpdconf['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
547
		$dhcpdconf['mac_allow'] = $_POST['mac_allow'];
548
		$dhcpdconf['mac_deny'] = $_POST['mac_deny'];
549
550
		unset($dhcpdconf['ntpserver']);
551 8f8682f7 Phil Davis
		if ($_POST['ntp1']) {
552 cba980f6 jim-p
			$dhcpdconf['ntpserver'][] = $_POST['ntp1'];
553 8f8682f7 Phil Davis
		}
554
		if ($_POST['ntp2']) {
555 cba980f6 jim-p
			$dhcpdconf['ntpserver'][] = $_POST['ntp2'];
556 8f8682f7 Phil Davis
		}
557 ad171999 Seth Mos
558 cba980f6 jim-p
		$dhcpdconf['tftp'] = $_POST['tftp'];
559
		$dhcpdconf['ldap'] = $_POST['ldap'];
560
		$dhcpdconf['netboot'] = ($_POST['netboot']) ? true : false;
561
		$dhcpdconf['nextserver'] = $_POST['nextserver'];
562
		$dhcpdconf['filename'] = $_POST['filename'];
563 7023c602 Charlie Root
		$dhcpdconf['filename32'] = $_POST['filename32'];
564
		$dhcpdconf['filename64'] = $_POST['filename64'];
565 cba980f6 jim-p
		$dhcpdconf['rootpath'] = $_POST['rootpath'];
566 18d316a5 heper
		unset($dhcpdconf['statsgraph']);
567
		if ($_POST['statsgraph']) {
568
			$dhcpdconf['statsgraph'] = $_POST['statsgraph'];
569 6303601e heper
			enable_rrd_graphing();
570 18d316a5 heper
		}
571 9c748b70 Scott Ullrich
572 d72b4114 Scott Ullrich
		// Handle the custom options rowhelper
573 8f8682f7 Phil Davis
		if (isset($dhcpdconf['numberoptions']['item'])) {
574 cba980f6 jim-p
			unset($dhcpdconf['numberoptions']['item']);
575 8f8682f7 Phil Davis
		}
576 6d1af0e9 jim-p
577 cba980f6 jim-p
		$dhcpdconf['numberoptions'] = $numberoptions;
578
579
		if (is_numeric($pool) && is_array($a_pools[$pool])) {
580
			$a_pools[$pool] = $dhcpdconf;
581
		} elseif ($act == "newpool") {
582
			$a_pools[] = $dhcpdconf;
583
		} else {
584
			$config['dhcpd'][$if] = $dhcpdconf;
585
		}
586 518030b3 Scott Ullrich
587 5b237745 Scott Ullrich
		write_config();
588 565488c9 Renato Botelho
	}
589
}
590 80933129 Bill Marquette
591 48ac0aa0 Phil Davis
if ((isset($_POST['submit']) || isset($_POST['apply'])) && (!$input_errors)) {
592 565488c9 Renato Botelho
	$retval = 0;
593
	$retvaldhcp = 0;
594
	$retvaldns = 0;
595
	/* dnsmasq_configure calls dhcpd_configure */
596
	/* no need to restart dhcpd twice */
597
	if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic']))	{
598
		$retvaldns = services_dnsmasq_configure();
599
		if ($retvaldns == 0) {
600
			clear_subsystem_dirty('hosts');
601
			clear_subsystem_dirty('staticmaps');
602 de792e62 jim-p
		}
603 565488c9 Renato Botelho
	} else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) {
604
		$retvaldns = services_unbound_configure();
605 4230ad16 Phil Davis
		if ($retvaldns == 0) {
606 565488c9 Renato Botelho
			clear_subsystem_dirty('unbound');
607 d3801fdb Renato Botelho
			clear_subsystem_dirty('hosts');
608
			clear_subsystem_dirty('staticmaps');
609 4230ad16 Phil Davis
		}
610 565488c9 Renato Botelho
	} else {
611
		$retvaldhcp = services_dhcpd_configure();
612 8f8682f7 Phil Davis
		if ($retvaldhcp == 0) {
613 565488c9 Renato Botelho
			clear_subsystem_dirty('staticmaps');
614 8f8682f7 Phil Davis
		}
615 5b237745 Scott Ullrich
	}
616 8f8682f7 Phil Davis
	if ($dhcpd_enable_changed) {
617 565488c9 Renato Botelho
		$retvalfc = filter_configure();
618 8f8682f7 Phil Davis
	}
619 565488c9 Renato Botelho
620 8f8682f7 Phil Davis
	if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) {
621 565488c9 Renato Botelho
		$retval = 1;
622 8f8682f7 Phil Davis
	}
623 b5f6e690 Stephen Beaver
624 565488c9 Renato Botelho
	$savemsg = get_std_save_message($retval);
625 5b237745 Scott Ullrich
}
626
627 cba980f6 jim-p
if ($act == "delpool") {
628
	if ($a_pools[$_GET['id']]) {
629
		unset($a_pools[$_GET['id']]);
630
		write_config();
631
		header("Location: services_dhcp.php?if={$if}");
632
		exit;
633
	}
634
}
635
636
if ($act == "del") {
637 5b237745 Scott Ullrich
	if ($a_maps[$_GET['id']]) {
638
		unset($a_maps[$_GET['id']]);
639
		write_config();
640 8f8682f7 Phil Davis
		if (isset($config['dhcpd'][$if]['enable'])) {
641 a368a026 Ermal Lu?i
			mark_subsystem_dirty('staticmaps');
642 8f8682f7 Phil Davis
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic'])) {
643 a368a026 Ermal Lu?i
				mark_subsystem_dirty('hosts');
644 8f8682f7 Phil Davis
			}
645 6a01ea44 Bill Marquette
		}
646 b5f6e690 Stephen Beaver
647 5b237745 Scott Ullrich
		header("Location: services_dhcp.php?if={$if}");
648
		exit;
649
	}
650
}
651 4df96eff Scott Ullrich
652 3c9befb9 Chris Buechler
// Build an HTML table that can be inserted into a Form_StaticText element
653 b5f6e690 Stephen Beaver
function build_pooltable() {
654
	global $a_pools;
655
656
	$pooltbl =	'<div class="table-responsive">';
657
	$pooltbl .=		'<table class="table table-striped table-hover table-condensed">';
658
	$pooltbl .=			'<thead>';
659
	$pooltbl .=				'<tr>';
660
	$pooltbl .=					'<th>' . gettext("Pool Start") . '</th>';
661
	$pooltbl .=					'<th>' . gettext("Pool End") . '</th>';
662
	$pooltbl .=					'<th>' . gettext("Description") . '</th>';
663
	$pooltbl .=					'<th></th>';
664
	$pooltbl .=				'</tr>';
665
	$pooltbl .=			'</thead>';
666
	$pooltbl .=			'<tbody>';
667
668
	if (is_array($a_pools)) {
669
		$i = 0;
670
		foreach ($a_pools as $poolent) {
671
			if (!empty($poolent['range']['from']) && !empty($poolent['range']['to'])) {
672
				$pooltbl .= '<tr>';
673
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
674
							htmlspecialchars($poolent['range']['from']) . '</td>';
675
676
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
677
							htmlspecialchars($poolent['range']['to']) . '</td>';
678
679
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
680
							htmlspecialchars($poolent['descr']) . '</td>';
681
682
				$pooltbl .= '<td><a class="btn btn-xs btn-info" href="services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '" />' . gettext('Edit') . '</a>';
683
684
				$pooltbl .= '<a class="btn btn-xs btn-danger" href="services_dhcp.php?if=' . htmlspecialchars($if) . '&act=delpool&id=' . $i . '" />' . gettext('Delete') . '</a></td>';
685
				$pooltbl .= '</tr>';
686
			}
687
		$i++;
688
		}
689
	}
690
691
	$pooltbl .=			'</tbody>';
692
	$pooltbl .=		'</table>';
693
	$pooltbl .= '</div>';
694
695
	return($pooltbl);
696
}
697
698 bf27317d Phil Davis
$pgtitle = array(gettext("Services"), gettext("DHCP Server"));
699 b32dd0a6 jim-p
$shortcut_section = "dhcp";
700 5224b8e7 jim-p
701 4df96eff Scott Ullrich
include("head.inc");
702
703 6e3488e9 Phil Davis
if ($input_errors) {
704 b5f6e690 Stephen Beaver
	print_input_errors($input_errors);
705 6e3488e9 Phil Davis
}
706 4df96eff Scott Ullrich
707 6e3488e9 Phil Davis
if ($savemsg) {
708 b5f6e690 Stephen Beaver
	print_info_box($savemsg, 'success');
709 6e3488e9 Phil Davis
}
710 678dfd0f Erik Fonnesbeck
711 b5f6e690 Stephen Beaver
if (isset($config['dhcrelay']['enable'])) {
712
	print_info_box(gettext("DHCP Relay is currently enabled. Cannot enable the DHCP Server service while the DHCP Relay is enabled on any interface."));
713
	include("foot.inc");
714
	exit;
715
}
716 4e9cd828 Seth Mos
717 6e3488e9 Phil Davis
if (is_subsystem_dirty('staticmaps')) {
718 b5f6e690 Stephen Beaver
	print_info_box_np(gettext("The static mapping configuration has been changed") . ".<br />" . gettext("You must apply the changes in order for them to take effect."));
719 6e3488e9 Phil Davis
}
720 b5f6e690 Stephen Beaver
721
/* active tabs */
722
$tab_array = array();
723
$tabscounter = 0;
724
$i = 0;
725 8a73f407 Stephen Beaver
726 b5f6e690 Stephen Beaver
foreach ($iflist as $ifent => $ifname) {
727
	$oc = $config['interfaces'][$ifent];
728
	if ((is_array($config['dhcpd'][$ifent]) && !isset($config['dhcpd'][$ifent]['enable']) && (!is_ipaddrv4($oc['ipaddr']))) ||
729 6e3488e9 Phil Davis
	    (!is_array($config['dhcpd'][$ifent]) && (!is_ipaddrv4($oc['ipaddr'])))) {
730 b5f6e690 Stephen Beaver
		continue;
731 518030b3 Scott Ullrich
	}
732 4e9cd828 Seth Mos
733 b5f6e690 Stephen Beaver
	if ($ifent == $if) {
734
		$active = true;
735
	} else {
736
		$active = false;
737 b1d132f5 Scott Ullrich
	}
738
739 b5f6e690 Stephen Beaver
	$tab_array[] = array($ifname, $active, "services_dhcp.php?if={$ifent}");
740
	$tabscounter++;
741
}
742 ad171999 Seth Mos
743 b5f6e690 Stephen Beaver
if ($tabscounter == 0) {
744
	print_info_box(gettext("The DHCP Server can only be enabled on interfaces configured with a static IPv4 address. This system has none."));
745
	include("foot.inc");
746
	exit;
747
}
748 1f1a08c8 jim-p
749 b5f6e690 Stephen Beaver
display_top_tabs($tab_array);
750
751 5da2095b Stephen Beaver
// This form uses a non-standard submit button name
752 b5f6e690 Stephen Beaver
$form = new Form(new Form_Button(
753
	'submit',
754
	gettext("Save")
755
));
756
757
$section = new Form_Section('General Options');
758
759
if (!is_numeric($pool) && !($act == "newpool")) {
760
	$section->addInput(new Form_Checkbox(
761
		'enable',
762
		'Enable',
763
		sprintf(gettext("Enable DHCP server on %s interface"), htmlspecialchars($iflist[$if])),
764
		$pconfig['enable']
765
	));
766
} else {
767
	$section->addInput(new Form_StaticText(
768
		null,
769 8a73f407 Stephen Beaver
		'<div class="alert alert-info"> Editing Pool-Specific Options. To return to the Interface, click its tab above. </div>'
770 b5f6e690 Stephen Beaver
	));
771
}
772 6c23757b Martin Fuchs
773 b5f6e690 Stephen Beaver
$section->addInput(new Form_Checkbox(
774
	'denyunknown',
775
	'Deny unknown clients',
776
	'Only the clients defined below will get DHCP leases from this server.',
777
	$pconfig['denyunknown']
778
));
779
780
if (is_numeric($pool) || ($act == "newpool")) {
781
	$section->addInput(new Form_Input(
782
		'descr',
783
		'Pool Description',
784
		'text',
785
		$pconfig['descr']
786
	));
787
}
788 6c23757b Martin Fuchs
789 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
790
	'Subnet',
791
	gen_subnet($ifcfgip, $ifcfgsn)
792
));
793 4e9cd828 Seth Mos
794 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
795
	'Subnet mask',
796
	gen_subnet_mask($ifcfgsn)
797
));
798 5b237745 Scott Ullrich
799 8a73f407 Stephen Beaver
// Compose a string to display the required address ranges
800 c18ba6bf Phil Davis
$range_from = ip2long(gen_subnetv4($ifcfgip, $ifcfgsn));
801 b5f6e690 Stephen Beaver
$range_from++;
802
803 c18ba6bf Phil Davis
$range_to = ip2long(gen_subnetv4_max($ifcfgip, $ifcfgsn));
804 b5f6e690 Stephen Beaver
$range_to--;
805
806
$rangestr = long2ip32($range_from) . ' - ' . long2ip32($range_to);
807
808
if (is_numeric($pool) || ($act == "newpool")) {
809
	$rangestr .= '<br />' . 'In-use DHCP Pool Ranges:';
810
	if (is_array($config['dhcpd'][$if]['range'])) {
811
		$rangestr .= '<br />' . $config['dhcpd'][$if]['range']['from'] . ' - ' . $config['dhcpd'][$if]['range']['to'];
812 3d7b7757 Chris Buechler
	}
813 b5f6e690 Stephen Beaver
814
	foreach ($a_pools as $p) {
815
		if (is_array($p['range'])) {
816
			$rangestr .= '<br />' . $p['range']['from'] . ' - ' . $p['range']['to'];
817 8f8682f7 Phil Davis
		}
818 934240ef Ermal Luçi
	}
819 b5f6e690 Stephen Beaver
}
820
821
$section->addInput(new Form_StaticText(
822
	'Available range',
823
	$rangestr
824
));
825
826
if ($is_olsr_enabled) {
827
	$section->addInput(new Form_Select(
828
		'netmask',
829
		'Subnet mask',
830
		$pconfig['netmask'],
831
		array_combine(range(32, 1, -1), range(32, 1, -1))
832
	));
833
}
834
835
$group = new Form_Group('Range');
836
837
$group->add(new Form_IpAddress(
838
	'range_from',
839
	null,
840
	$pconfig['range_from']
841
))->setHelp('From');
842
843
$group->add(new Form_IpAddress(
844
	'range_to',
845
	null,
846
	$pconfig['range_to']
847
))->setHelp('To');
848
849
$section->add($group);
850
851
$form->add($section);
852
853
if (!is_numeric($pool) && !($act == "newpool")) {
854
	$section = new Form_Section('Additional pools');
855
856
	$btnaddpool = new Form_Button(
857
		'btnaddpool',
858
		'Add pool',
859
		'services_dhcp.php?if=' . htmlspecialchars($if) . '&act=newpool'
860
	);
861
862
	$section->addInput(new Form_StaticText(
863
		'Add',
864
		$btnaddpool
865
	))->setHelp('If you need additional pools of addresses inside of this subnet outside the above Range, they may be specified here');
866
867
	if (is_array($a_pools)) {
868
		$section->addInput(new Form_StaticText(
869
			null,
870
			build_pooltable()
871
		));
872 f0cdf141 Scott Ullrich
	}
873 b5f6e690 Stephen Beaver
874
	$form->add($section);
875
}
876
877
$section = new Form_Section('Servers');
878
879
$section->addInput(new Form_IpAddress(
880
	'wins1',
881
	'WINS servers',
882
	$pconfig['wins1']
883
))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'WINS Server 1');
884
885
$section->addInput(new Form_IpAddress(
886
	'wins2',
887
	null,
888
	$pconfig['wins2']
889
))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'WINS Server 2');
890
891 6e3488e9 Phil Davis
for ($idx=1; $idx<=4; $idx++) {
892 b5f6e690 Stephen Beaver
	$section->addInput(new Form_IpAddress(
893
		'dns' . $idx,
894
		($idx == 1) ? 'DNS servers':null,
895
		$pconfig['dns' . $idx]
896
	))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'DNS Server ' . $idx)->setHelp(($idx == 4) ? 'Leave blank to use the system default DNS servers, use this interface\'s IP if DNS Forwarder or Resolver is enabled, otherwise use the servers configured on the General page':'');
897
}
898
899
$form->add($section);
900
901
$section = new Form_Section('Other options');
902
903
$section->addInput(new Form_IpAddress(
904
	'gateway',
905
	'Gateway',
906
	$pconfig['gateway']
907
))->setPattern('[.a-zA-Z0-9_]+')
908
  ->setHelp('The default is to use the IP on this interface of the firewall as the gateway. Specify an alternate gateway here if this is not the correct gateway for your network. Type "none" for no gateway assignment');
909
910
$section->addInput(new Form_Input(
911
	'domain',
912
	'Domain name',
913
	'text',
914
	$pconfig['domain']
915
))->setHelp('The default is to use the domain name of this system as the default domain name provided by DHCP. You may specify an alternate domain name here');
916
917
$section->addInput(new Form_Input(
918
	'domainsearchlist',
919
	'Domain search list',
920
	'text',
921
	$pconfig['domainsearchlist']
922
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator');
923
924
$section->addInput(new Form_Input(
925
	'deftime',
926
	'Default lease time',
927
	'number',
928
	$pconfig['deftime']
929
))->setHelp('This is used for clients that do not ask for a specific expiration time. The default is 7200 seconds');
930
931
$section->addInput(new Form_Input(
932
	'maxtime',
933
	'Maximum lease time',
934
	'number',
935
	$pconfig['maxtime']
936
))->setHelp('This is the maximum lease time for clients that ask for a specific expiration time. The default is 86400 seconds');
937
938
if (!is_numeric($pool) && !($act == "newpool")) {
939
	$section->addInput(new Form_IpAddress(
940
		'failover_peerip',
941
		'Failover peer IP',
942
		$pconfig['failover_peerip']
943
	))->setHelp('Leave blank to disable. Enter the interface IP address of the other machine. Machines must be using CARP.' .
944
				'Interface\'s advskew determines whether the DHCPd process is Primary or Secondary. Ensure one machine\'s advskew < 20 (and the other is > 20).');
945
}
946
947
if (!is_numeric($pool) && !($act == "newpool")) {
948
	$section->addInput(new Form_Checkbox(
949
		'staticarp',
950
		'Static ARP',
951
		'Enable Static ARP entries',
952
		$pconfig['staticarp']
953
	))->setHelp('This option persists even if DHCP server is disabled. Only the machines listed below will be able to communicate with the firewall on this NIC.');
954
955
	$section->addInput(new Form_Checkbox(
956
		'dhcpleaseinlocaltime',
957
		'Time format change',
958
		'Change DHCP display lease time from UTC to local time',
959
		$pconfig['dhcpleaseinlocaltime']
960
	))->setHelp('By default DHCP leases are displayed in UTC time.	By checking this box DHCP lease time will be displayed in local time and set to the time zone selected.' .
961
				' This will be used for all DHCP interfaces lease time');
962 18d316a5 heper
	$section->addInput(new Form_Checkbox(
963
		'statsgraph',
964 61237194 Chris Buechler
		'Statistics graphs',
965
		'Enable RRD statistics graphs',
966 18d316a5 heper
		$pconfig['statsgraph']
967 61237194 Chris Buechler
	))->setHelp('Enable this to add DHCP leases statistics to the RRD graphs. Disabled by default.');
968 b5f6e690 Stephen Beaver
}
969
970
// DDNS
971
$btnadv = new Form_Button(
972
	'btnadvdns',
973
	'Advanced'
974
);
975
976
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
977
978
$section->addInput(new Form_StaticText(
979
	'Dynamic DNS',
980
	$btnadv
981
));
982
983
$section->addInput(new Form_Checkbox(
984
	'ddnsupdate',
985
	null,
986
	'Enable registration of DHCP client names in DNS',
987
	$pconfig['ddnsupdate']
988
));
989
990
$section->addInput(new Form_Input(
991
	'ddnsdomain',
992
	'DDNS Domain',
993
	'number',
994
	$pconfig['ddnsdomain']
995
))->setHelp('Leave blank to disable dynamic DNS registration.' . '<br />' .
996
			'Enter the dynamic DNS domain which will be used to register client names in the DNS server.');
997
998
$section->addInput(new Form_IpAddress(
999
	'ddnsdomainprimary',
1000
	'Primary DDNS address',
1001
	$pconfig['ddnsdomainprimary']
1002
))->setHelp('Primary domain name server IP address for the dynamic domain name');
1003
1004
$section->addInput(new Form_Input(
1005
	'ddnsdomainkeyname',
1006
	'DNS Domain key',
1007
	'text',
1008
	$pconfig['ddnsdomainkeyname']
1009
))->setHelp('Dynamic DNS domain key name which will be used to register client names in the DNS server');
1010
1011
$section->addInput(new Form_Input(
1012
	'ddnsdomainkey',
1013
	'DNS Domain key secret',
1014
	'text',
1015
	$pconfig['ddnsdomainkey']
1016
))->setHelp('Dynamic DNS domain key secret which will be used to register client names in the DNS server');
1017
1018
// Advanced MAC
1019
$btnadv = new Form_Button(
1020
	'btnadvmac',
1021
	'Advanced'
1022
);
1023
1024
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
1025
1026
$section->addInput(new Form_StaticText(
1027
	'MAC address control',
1028
	$btnadv
1029
));
1030
1031
$section->addInput(new Form_Input(
1032
	'mac_allow',
1033
	'Allow',
1034
	'text',
1035
	$pconfig['mac_allow']
1036
))->setHelp('List of partial MAC addresses to allow, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1037
1038
$section->addInput(new Form_Input(
1039
	'mac_deny',
1040
	'Deny',
1041
	'text',
1042
	$pconfig['mac_deny']
1043
))->setHelp('List of partial MAC addresses to deny access, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1044
1045
// Advanced NTP
1046
$btnadv = new Form_Button(
1047
	'btnadvntp',
1048
	'Advanced'
1049
);
1050
1051
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
1052
1053
$section->addInput(new Form_StaticText(
1054
	'NTP servers',
1055
	$btnadv
1056
));
1057
1058
$section->addInput(new Form_IpAddress(
1059
	'ntp1',
1060 bf27317d Phil Davis
	null,
1061 b5f6e690 Stephen Beaver
	$pconfig['ntp1']
1062 bf27317d Phil Davis
))->setAttribute('placeholder', 'NTP Server 1');
1063 b5f6e690 Stephen Beaver
1064
$section->addInput(new Form_IpAddress(
1065
	'ntp2',
1066 bf27317d Phil Davis
	null,
1067 b5f6e690 Stephen Beaver
	$pconfig['ntp2']
1068 bf27317d Phil Davis
))->setAttribute('placeholder', 'NTP Server 2');
1069 b5f6e690 Stephen Beaver
1070
// Advanced TFTP
1071
$btnadv = new Form_Button(
1072
	'btnadvtftp',
1073
	'Advanced'
1074
);
1075
1076
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
1077
1078
$section->addInput(new Form_StaticText(
1079
	'TFTP server',
1080
	$btnadv
1081
));
1082
1083
$section->addInput(new Form_IpAddress(
1084
	'tftp',
1085 bf27317d Phil Davis
	null,
1086 b5f6e690 Stephen Beaver
	$pconfig['tftp']
1087
))->setHelp('Leave blank to disable.  Enter a full hostname or IP for the TFTP server')->setPattern('[.a-zA-Z0-9_]+');
1088
1089
// Advanced LDAP
1090
$btnadv = new Form_Button(
1091
	'btnadvldap',
1092
	'Advanced'
1093
);
1094
1095
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
1096
1097
$section->addInput(new Form_StaticText(
1098
	'LDAP URI',
1099
	$btnadv
1100
));
1101
1102
$section->addInput(new Form_Input(
1103
	'ldap',
1104
	null,
1105
	'text',
1106
	$pconfig['ldap']
1107
))->setHelp('Leave blank to disable. Enter a full URI for the LDAP server in the form ldap://ldap.example.com/dc=example,dc=com ');
1108
1109
// Advanced NETBOOT
1110
$btnadv = new Form_Button(
1111
	'btnadvboot',
1112
	'Advanced'
1113
);
1114
1115
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
1116
1117
$section->addInput(new Form_StaticText(
1118
	'Network booting',
1119
	$btnadv
1120
));
1121
1122
$section->addInput(new Form_Checkbox(
1123
	'netboot',
1124
	null,
1125
	'Enables network booting',
1126
	$pconfig['netboot']
1127
));
1128
1129
$section->addInput(new Form_IpAddress(
1130
	'nextserver',
1131
	'Next Server',
1132
	$pconfig['nextserver']
1133 8a73f407 Stephen Beaver
))->setHelp('Enter the IP address of the next server');
1134 b5f6e690 Stephen Beaver
1135
$section->addInput(new Form_Input(
1136
	'filename',
1137
	'Default BIOS file name',
1138
	'text',
1139
	$pconfig['filename']
1140
));
1141
1142
$section->addInput(new Form_Input(
1143
	'filename32',
1144
	'UEFI 32 bit file name',
1145
	'text',
1146
	$pconfig['filename32']
1147
));
1148
1149
$section->addInput(new Form_Input(
1150
	'filename64',
1151
	'UEFI 64 bit file name',
1152
	'text',
1153
	$pconfig['filename64']
1154
))->setHelp('You need both a filename and a boot server configured for this to work! ' .
1155
			'You will need all three filenames and a boot server configured for UEFI to work! ');
1156
1157
$section->addInput(new Form_Input(
1158
	'rootpath',
1159
	'Root path',
1160
	'text',
1161
	$pconfig['rootpath']
1162
))->setHelp('string-format: iscsi:(servername):(protocol):(port):(LUN):targetname ');
1163
1164
// Advanced Additional options
1165
$btnadv = new Form_Button(
1166
	'btnadvopts',
1167
	'Advanced'
1168
);
1169
1170
$btnadv->removeClass('btn-primary')->addClass('btn-default btn-sm');
1171
1172
$section->addInput(new Form_StaticText(
1173
	'Additional BOOTP/DHCP Options',
1174
	$btnadv
1175
));
1176
1177
$form->add($section);
1178
1179
$section = new Form_Section('Additional BOOTP/DHCP Options');
1180
$section->addClass('adnlopts');
1181
1182
$section->addInput(new Form_StaticText(
1183
	null,
1184
	'<div class="alert alert-info"> ' . gettext('Enter the DHCP option number and the value for each item you would like to include in the DHCP lease information. ' .
1185
	'For a list of available options please visit this ') . '<a href="http://www.iana.org/assignments/bootp-dhcp-parameters/" target="_blank">' . gettext("URL") . '</a></div>'
1186
));
1187
1188 6e3488e9 Phil Davis
if (!$pconfig['numberoptions']) {
1189 b5f6e690 Stephen Beaver
	$pconfig['numberoptions']['item']  = array(array('number' => '', 'type' => 'text', 'value' => ''));
1190
}
1191
1192
$customitemtypes = array(
1193
	'text' => gettext('Text'), 'string' => gettext('String'), 'boolean' => gettext('Boolean'),
1194
	'unsigned integer 8' => gettext('Unsigned 8-bit integer'), 'unsigned integer 16' => gettext('Unsigned 16-bit integer'), 'unsigned integer 32' => gettext('Unsigned 32-bit integer'),
1195
	'signed integer 8' => gettext('Signed 8-bit integer'), 'signed integer 16' => gettext('Signed 16-bit integer'), 'signed integer 32' => gettext('Signed 32-bit integer'), 'ip-address' => gettext('IP address or host')
1196
);
1197
1198
$numrows = count($item) -1;
1199
$counter = 0;
1200
1201
$numrows = count($pconfig['numberoptions']['item']) -1;
1202
1203
foreach ($pconfig['numberoptions']['item'] as $item) {
1204
	$number = $item['number'];
1205
	$itemtype = $item['type'];
1206
	$value = $item['value'];
1207
1208
	$group = new Form_Group(($counter == 0) ? 'Option':null);
1209
	$group->addClass('repeatable');
1210
1211
	$group->add(new Form_Input(
1212
		'number' . $counter,
1213
		null,
1214
		'text',
1215
		$number
1216
	))->setHelp($numrows == $counter ? 'Number':null);
1217
1218
1219
	$group->add(new Form_Select(
1220
		'itemtype' . $counter,
1221
		null,
1222
		$itemtype,
1223
		$customitemtypes
1224 8a73f407 Stephen Beaver
	))->setWidth(3)->setHelp($numrows == $counter ? 'Type':null);
1225 b5f6e690 Stephen Beaver
1226
	$group->add(new Form_Input(
1227
		'value' . $counter,
1228
		null,
1229
		'text',
1230
		$value
1231
	))->setHelp($numrows == $counter ? 'Value':null);
1232
1233
	$group->add(new Form_Button(
1234
		'deleterow' . $counter,
1235
		'Delete'
1236
	))->removeClass('btn-primary')->addClass('btn-warning');
1237
1238
	$section->add($group);
1239
1240
	$counter++;
1241
}
1242
1243
$section->addInput(new Form_Button(
1244
	'addrow',
1245
	'Add'
1246
))->removeClass('btn-primary')->addClass('btn-success');
1247
1248
$form->add($section);
1249
1250
if ($act == "newpool") {
1251
	$form->addGlobal(new Form_Input(
1252
		'act',
1253
		null,
1254
		'hidden',
1255
		'newpool'
1256
	));
1257
}
1258
1259
if (is_numeric($pool)) {
1260
	$form->addGlobal(new Form_Input(
1261
		'pool',
1262
		null,
1263
		'hidden',
1264
		$pool
1265
	));
1266
}
1267
1268
$form->addGlobal(new Form_Input(
1269
	'if',
1270
	null,
1271
	'hidden',
1272
	$if
1273
));
1274
1275
print($form);
1276
1277
// DHCP Static Mappings table
1278
1279
if (!is_numeric($pool) && !($act == "newpool")) {
1280 de792e62 jim-p
?>
1281 b5f6e690 Stephen Beaver
1282
<div class="panel panel-default">
1283 7683c990 Chris Buechler
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCP Static Mappings for this interface")?></h2></div>
1284 b5f6e690 Stephen Beaver
	<div class="table-responsive">
1285
			<table class="table table-striped table-hover table-condensed">
1286
				<thead>
1287
					<tr>
1288
						<th><?=gettext("Static ARP")?></th>
1289
						<th><?=gettext("MAC address")?></th>
1290
						<th><?=gettext("IP address")?></th>
1291
						<th><?=gettext("Hostname")?></th>
1292
						<th><?=gettext("Description")?></th>
1293
						<th></th>
1294
					</tr>
1295
				</thead>
1296 8f8682f7 Phil Davis
<?php
1297 b5f6e690 Stephen Beaver
	if (is_array($a_maps)) {
1298
		$i = 0;
1299 8f8682f7 Phil Davis
?>
1300 b5f6e690 Stephen Beaver
				<tbody>
1301 8f8682f7 Phil Davis
<?php
1302 b5f6e690 Stephen Beaver
		foreach ($a_maps as $mapent) {
1303 8f8682f7 Phil Davis
?>
1304 b5f6e690 Stephen Beaver
					<tr>
1305
						<td align="center" ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1306
							<?php if (isset($mapent['arp_table_static_entry'])): ?>
1307 1b7379f9 Jared Dillard
								<i class="fa fa-check"></i>
1308 b5f6e690 Stephen Beaver
							<?php endif; ?>
1309
						</td>
1310
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1311
							<?=htmlspecialchars($mapent['mac'])?>
1312
						</td>
1313
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1314
							<?=htmlspecialchars($mapent['ipaddr'])?>
1315
						</td>
1316
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1317
							<?=htmlspecialchars($mapent['hostname'])?>
1318
						</td>
1319
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1320
							<?=htmlspecialchars($mapent['descr'])?>
1321
						</td>
1322
						<td>
1323 9a6a8329 heper
							<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>"	href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>"></a>
1324 33f0b0d5 Stephen Beaver
							<a class="fa fa-trash"	title="<?=gettext('Delete static mapping')?>"	href="services_dhcp.php?if=<?=htmlspecialchars($if)?>&amp;act=del&amp;id=<?=$i?>"></a>
1325 b5f6e690 Stephen Beaver
						</td>
1326
					</tr>
1327 8f8682f7 Phil Davis
<?php
1328 b5f6e690 Stephen Beaver
		$i++;
1329
		}
1330 8f8682f7 Phil Davis
?>
1331 b5f6e690 Stephen Beaver
				</tbody>
1332 8f8682f7 Phil Davis
<?php
1333 b5f6e690 Stephen Beaver
	}
1334 8f8682f7 Phil Davis
?>
1335 82f54a42 Colin Fleming
		</table>
1336 b5f6e690 Stephen Beaver
	</div>
1337
</div>
1338 c9679d8c Stephen Beaver
1339 c10cb196 Stephen Beaver
<nav class="action-buttons">
1340 c9679d8c Stephen Beaver
	<a href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>" class="btn btn-sm btn-success">
1341 9d5a20cf heper
		<i class="fa fa-plus icon-embed-btn"></i>
1342 c9679d8c Stephen Beaver
		<?=gettext("Add")?>
1343
	</a>
1344
</nav>
1345 8f8682f7 Phil Davis
<?php
1346 b5f6e690 Stephen Beaver
}
1347 8f8682f7 Phil Davis
?>
1348
1349 8fd9052f Colin Fleming
<script type="text/javascript">
1350 b5f6e690 Stephen Beaver
//<![CDATA[
1351 6e3488e9 Phil Davis
events.push(function() {
1352 b5f6e690 Stephen Beaver
1353
	// Show advanced DNS options ======================================================================================
1354
	var showadvdns = false;
1355
1356
	function show_advdns() {
1357
<?php
1358
		if (!$pconfig['ddnsupdate'] && empty($pconfig['ddnsdomain']) && empty($pconfig['ddnsdomainprimary']) &&
1359 6e3488e9 Phil Davis
		    empty($pconfig['ddnsdomainkeyname']) && empty($pconfig['ddnsdomainkey'])) {
1360 b5f6e690 Stephen Beaver
			$hide = false;
1361 6e3488e9 Phil Davis
		} else {
1362 b5f6e690 Stephen Beaver
			$hide = true;
1363 6e3488e9 Phil Davis
		}
1364 8f8682f7 Phil Davis
?>
1365 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1366 b5f6e690 Stephen Beaver
1367
		hideCheckbox('ddnsupdate', !showadvdns && !hide);
1368
		hideInput('ddnsdomain', !showadvdns && !hide);
1369
		hideInput('ddnsdomainprimary', !showadvdns && !hide);
1370
		hideInput('ddnsdomainkeyname', !showadvdns && !hide);
1371
		hideInput('ddnsdomainkey', !showadvdns && !hide);
1372 8a73f407 Stephen Beaver
		hideInput('btnadvdns', hide);
1373 b5f6e690 Stephen Beaver
		showadvdns = !showadvdns;
1374
	}
1375
1376
	$('#btnadvdns').prop('type', 'button');
1377
1378
	$('#btnadvdns').click(function(event) {
1379
		show_advdns();
1380
	});
1381
1382
 // Show advanced MAC options ======================================================================================
1383
	var showadvmac = false;
1384
1385
	function show_advmac() {
1386 8f8682f7 Phil Davis
<?php
1387 6e3488e9 Phil Davis
		if (empty($pconfig['mac_allow']) && empty($pconfig['mac_deny'])) {
1388 b5f6e690 Stephen Beaver
			$hide = false;
1389 6e3488e9 Phil Davis
		} else {
1390 b5f6e690 Stephen Beaver
			$hide = true;
1391 6e3488e9 Phil Davis
		}
1392 8f8682f7 Phil Davis
?>
1393 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1394 b5f6e690 Stephen Beaver
1395
		hideInput('mac_allow', !showadvmac && !hide);
1396
		hideInput('mac_deny', !showadvmac && !hide);
1397 8a73f407 Stephen Beaver
		hideInput('btnadvmac', hide);
1398 b5f6e690 Stephen Beaver
1399
		showadvmac = !showadvmac;
1400
	}
1401
1402
	$('#btnadvmac').prop('type', 'button');
1403
1404
	$('#btnadvmac').click(function(event) {
1405
		show_advmac();
1406
	});
1407
1408
  // Show advanced NTP options ======================================================================================
1409
	var showadvntp = false;
1410
1411
	function show_advntp() {
1412 8f8682f7 Phil Davis
<?php
1413 6e3488e9 Phil Davis
		if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1414 b5f6e690 Stephen Beaver
			$hide = false;
1415 6e3488e9 Phil Davis
		} else {
1416 b5f6e690 Stephen Beaver
			$hide = true;
1417 6e3488e9 Phil Davis
		}
1418 8f8682f7 Phil Davis
?>
1419 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1420 b5f6e690 Stephen Beaver
1421
		hideInput('ntp1', !showadvntp && !hide);
1422
		hideInput('ntp2', !showadvntp && !hide);
1423 8a73f407 Stephen Beaver
		hideInput('btnadvntp', hide);
1424 b5f6e690 Stephen Beaver
1425
		showadvntp = !showadvntp;
1426
	}
1427
1428
	$('#btnadvntp').prop('type', 'button');
1429
1430
	$('#btnadvntp').click(function(event) {
1431
		show_advntp();
1432
	});
1433
1434
   // Show advanced TFTP options ======================================================================================
1435
	var showadvtftp = false;
1436
1437
	function show_advtftp() {
1438 8f8682f7 Phil Davis
<?php
1439 6e3488e9 Phil Davis
		if (empty($pconfig['tftp'])) {
1440 b5f6e690 Stephen Beaver
			$hide = false;
1441 6e3488e9 Phil Davis
		} else {
1442 b5f6e690 Stephen Beaver
			$hide = true;
1443 6e3488e9 Phil Davis
		}
1444 8f8682f7 Phil Davis
?>
1445 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1446 b5f6e690 Stephen Beaver
1447
		hideInput('tftp', !showadvtftp && !hide);
1448 8a73f407 Stephen Beaver
		hideInput('btnadvtftp', hide);
1449 b5f6e690 Stephen Beaver
1450
		showadvtftp = !showadvtftp;
1451
	}
1452
1453
	$('#btnadvtftp').prop('type', 'button');
1454
1455
	$('#btnadvtftp').click(function(event) {
1456
		show_advtftp();
1457
	});
1458
1459
   // Show advanced LDAP options ======================================================================================
1460
	var showadvldap = false;
1461
1462
	function show_advldap() {
1463 8f8682f7 Phil Davis
<?php
1464 6e3488e9 Phil Davis
		if (empty($pconfig['ldap'])) {
1465 b5f6e690 Stephen Beaver
			$hide = false;
1466 6e3488e9 Phil Davis
		} else {
1467 b5f6e690 Stephen Beaver
			$hide = true;
1468 6e3488e9 Phil Davis
		}
1469 8f8682f7 Phil Davis
?>
1470 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1471 b5f6e690 Stephen Beaver
1472
		hideInput('ldap', !showadvldap && !hide);
1473 8a73f407 Stephen Beaver
		hideInput('btnadvldap', hide);
1474 b5f6e690 Stephen Beaver
1475
		showadvldap = !showadvldap;
1476
	}
1477
1478
	$('#btnadvldap').prop('type', 'button');
1479
1480
	$('#btnadvldap').click(function(event) {
1481
		show_advldap();
1482
	});
1483
1484
   // Show advanced NETBOOT options ===================================================================================
1485
	var showadvboot = false;
1486
1487
	function show_advboot() {
1488 8f8682f7 Phil Davis
<?php
1489 b5f6e690 Stephen Beaver
		if (!$pconfig['netboot'] && empty($pconfig['nextserver']) && empty($pconfig['filename']) && empty($pconfig['filename32']) &&
1490 6e3488e9 Phil Davis
		    empty($pconfig['filename64']) && empty($pconfig['rootpath'])) {
1491 b5f6e690 Stephen Beaver
			$hide = false;
1492 6e3488e9 Phil Davis
		} else {
1493 b5f6e690 Stephen Beaver
			$hide = true;
1494 6e3488e9 Phil Davis
		}
1495 8f8682f7 Phil Davis
?>
1496 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1497 b5f6e690 Stephen Beaver
1498
		hideCheckbox('netboot', !showadvboot && !hide);
1499
		hideInput('nextserver', !showadvboot && !hide);
1500
		hideInput('filename', !showadvboot && !hide);
1501
		hideInput('filename32', !showadvboot && !hide);
1502
		hideInput('filename64', !showadvboot && !hide);
1503
		hideInput('rootpath', !showadvboot && !hide);
1504 8a73f407 Stephen Beaver
		hideInput('btnadvboot', hide);
1505 b5f6e690 Stephen Beaver
1506
		showadvboot = !showadvboot;
1507
	}
1508
1509
	$('#btnadvboot').prop('type', 'button');
1510
1511
	$('#btnadvboot').click(function(event) {
1512
		show_advboot();
1513
	});
1514
1515 eef93144 Jared Dillard
	// Show advanced additional opts options ===========================================================================
1516 b5f6e690 Stephen Beaver
	var showadvopts = false;
1517
1518
	function show_advopts() {
1519 8f8682f7 Phil Davis
<?php
1520 6e3488e9 Phil Davis
		if (empty($pconfig['numberoptions']) ||
1521
		    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1522 b5f6e690 Stephen Beaver
			$hide = false;
1523 6e3488e9 Phil Davis
		} else {
1524 b5f6e690 Stephen Beaver
			$hide = true;
1525 6e3488e9 Phil Davis
		}
1526 8f8682f7 Phil Davis
?>
1527 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1528 b5f6e690 Stephen Beaver
1529
		hideClass('adnlopts', !showadvopts && !hide);
1530 8a73f407 Stephen Beaver
		hideInput('btnadvopts', hide);
1531 b5f6e690 Stephen Beaver
1532
		showadvopts = !showadvopts;
1533
	}
1534
1535
	$('#btnadvopts').prop('type', 'button');
1536
1537
	$('#btnadvopts').click(function(event) {
1538
		show_advopts();
1539
	});
1540
1541 eef93144 Jared Dillard
	// ---------- On initial page load ------------------------------------------------------------
1542
1543 b5f6e690 Stephen Beaver
	show_advdns();
1544
	show_advmac();
1545
	show_advntp();
1546
	show_advtftp();
1547
	show_advldap();
1548
	show_advboot();
1549
	show_advopts();
1550 0bc61baa Stephen Beaver
1551
	// Suppress "Delete row" button if there are fewer than two rows
1552
	checkLastRow();
1553 b5f6e690 Stephen Beaver
});
1554 180db186 Colin Fleming
//]]>
1555 5b237745 Scott Ullrich
</script>
1556 b5f6e690 Stephen Beaver
1557 3c9befb9 Chris Buechler
<?php include("foot.inc");