Project

General

Profile

Download (47.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 e7940d2e Phil Davis
140
	if (!is_array($config['dhcpd'][$if]['staticmap'])) {
141
		$dhcpdconf['staticmap'] = array();
142
	}
143
144
	$a_maps = &$config['dhcpd'][$if]['staticmap'];
145 cba980f6 jim-p
}
146
if (is_array($dhcpdconf)) {
147
	// Global Options
148
	if (!is_numeric($pool) && !($act == "newpool")) {
149
		$pconfig['enable'] = isset($dhcpdconf['enable']);
150
		$pconfig['staticarp'] = isset($dhcpdconf['staticarp']);
151
		// No reason to specify this per-pool, per the dhcpd.conf man page it needs to be in every
152 b5f6e690 Stephen Beaver
		//	 pool and should be specified in every pool both nodes share, so we'll treat it as global
153 cba980f6 jim-p
		$pconfig['failover_peerip'] = $dhcpdconf['failover_peerip'];
154 466aae83 Phil Davis
155
		// dhcpleaseinlocaltime is global to all interfaces. So if it is selected on any interface,
156
		// then show it true/checked.
157
		foreach ($config['dhcpd'] as $dhcpdifitem) {
158
			$dhcpleaseinlocaltime = $dhcpdifitem['dhcpleaseinlocaltime'];
159 8f8682f7 Phil Davis
			if ($dhcpleaseinlocaltime) {
160 466aae83 Phil Davis
				break;
161 8f8682f7 Phil Davis
			}
162 466aae83 Phil Davis
		}
163
164
		$pconfig['dhcpleaseinlocaltime'] = $dhcpleaseinlocaltime;
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 3475eb04 Andrew Pilloud
	$pconfig['nonak'] = isset($dhcpdconf['nonak']);
185 cba980f6 jim-p
	$pconfig['ddnsdomain'] = $dhcpdconf['ddnsdomain'];
186 87019fc4 Andres Petralli
	$pconfig['ddnsdomainprimary'] = $dhcpdconf['ddnsdomainprimary'];
187
	$pconfig['ddnsdomainkeyname'] = $dhcpdconf['ddnsdomainkeyname'];
188
	$pconfig['ddnsdomainkey'] = $dhcpdconf['ddnsdomainkey'];
189 cba980f6 jim-p
	$pconfig['ddnsupdate'] = isset($dhcpdconf['ddnsupdate']);
190
	$pconfig['mac_allow'] = $dhcpdconf['mac_allow'];
191
	$pconfig['mac_deny'] = $dhcpdconf['mac_deny'];
192 8f8682f7 Phil Davis
	list($pconfig['ntp1'], $pconfig['ntp2']) = $dhcpdconf['ntpserver'];
193 cba980f6 jim-p
	$pconfig['tftp'] = $dhcpdconf['tftp'];
194
	$pconfig['ldap'] = $dhcpdconf['ldap'];
195
	$pconfig['netboot'] = isset($dhcpdconf['netboot']);
196
	$pconfig['nextserver'] = $dhcpdconf['nextserver'];
197
	$pconfig['filename'] = $dhcpdconf['filename'];
198 7023c602 Charlie Root
	$pconfig['filename32'] = $dhcpdconf['filename32'];
199
	$pconfig['filename64'] = $dhcpdconf['filename64'];
200 cba980f6 jim-p
	$pconfig['rootpath'] = $dhcpdconf['rootpath'];
201
	$pconfig['netmask'] = $dhcpdconf['netmask'];
202
	$pconfig['numberoptions'] = $dhcpdconf['numberoptions'];
203 18d316a5 heper
	$pconfig['statsgraph'] = $dhcpdconf['statsgraph'];
204 89019922 Ermal Luçi
}
205 31c59d0d Scott Ullrich
206 51cd7a1e Evgeny Yurchenko
$ifcfgip = $config['interfaces'][$if]['ipaddr'];
207
$ifcfgsn = $config['interfaces'][$if]['subnet'];
208 5b237745 Scott Ullrich
209 1f1a08c8 jim-p
function validate_partial_mac_list($maclist) {
210
	$macs = explode(',', $maclist);
211
212
	// Loop through and look for invalid MACs.
213 8f8682f7 Phil Davis
	foreach ($macs as $mac) {
214
		if (!is_macaddr($mac, true)) {
215 1f1a08c8 jim-p
			return false;
216 8f8682f7 Phil Davis
		}
217
	}
218 b5f6e690 Stephen Beaver
219 1f1a08c8 jim-p
	return true;
220
}
221
222 565488c9 Renato Botelho
if (isset($_POST['submit'])) {
223 5b237745 Scott Ullrich
224
	unset($input_errors);
225 b7597d4e Bill Marquette
226 5b237745 Scott Ullrich
	$pconfig = $_POST;
227
228 6d1af0e9 jim-p
	$numberoptions = array();
229 6c07db48 Phil Davis
	for ($x = 0; $x < 99; $x++) {
230 8f8682f7 Phil Davis
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
231 6d1af0e9 jim-p
			$numbervalue = array();
232
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
233 678dfd0f Erik Fonnesbeck
			$numbervalue['type'] = htmlspecialchars($_POST["itemtype{$x}"]);
234 65cce9d7 Renato Botelho
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
235 6d1af0e9 jim-p
			$numberoptions['item'][] = $numbervalue;
236
		}
237
	}
238 b5f6e690 Stephen Beaver
239 466aae83 Phil Davis
	// Reload the new pconfig variable that the form uses.
240 6d1af0e9 jim-p
	$pconfig['numberoptions'] = $numberoptions;
241
242 5b237745 Scott Ullrich
	/* input validation */
243 cba980f6 jim-p
	if ($_POST['enable'] || is_numeric($pool) || $act == "newpool") {
244 5b237745 Scott Ullrich
		$reqdfields = explode(" ", "range_from range_to");
245 8f8682f7 Phil Davis
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
246 e9f147c8 Scott Ullrich
247 507628d5 Renato Botelho
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
248 de792e62 jim-p
249 8f8682f7 Phil Davis
		if (($_POST['range_from'] && !is_ipaddrv4($_POST['range_from']))) {
250 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid range must be specified.");
251 8f8682f7 Phil Davis
		}
252
		if (($_POST['range_to'] && !is_ipaddrv4($_POST['range_to']))) {
253 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid range must be specified.");
254 8f8682f7 Phil Davis
		}
255
		if (($_POST['gateway'] && $_POST['gateway'] != "none" && !is_ipaddrv4($_POST['gateway']))) {
256 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the gateway.");
257 8f8682f7 Phil Davis
		}
258
		if (($_POST['wins1'] && !is_ipaddrv4($_POST['wins1'])) || ($_POST['wins2'] && !is_ipaddrv4($_POST['wins2']))) {
259 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the primary/secondary WINS servers.");
260 8f8682f7 Phil Davis
		}
261 9bc59815 Evgeny Yurchenko
		$parent_ip = get_interface_ip($_POST['if']);
262 1bd021e3 timdufrane
		if (is_ipaddrv4($parent_ip) && $_POST['gateway'] && $_POST['gateway'] != "none") {
263 9bc59815 Evgeny Yurchenko
			$parent_sn = get_interface_subnet($_POST['if']);
264 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'])) {
265 9bc59815 Evgeny Yurchenko
				$input_errors[] = sprintf(gettext("The gateway address %s does not lie within the chosen interface's subnet."), $_POST['gateway']);
266 8f8682f7 Phil Davis
			}
267 45d1024d Scott Ullrich
		}
268 b5f6e690 Stephen Beaver
269 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']))) {
270 3b5707db Phil Davis
			$input_errors[] = gettext("A valid IP address must be specified for each of the DNS servers.");
271 8f8682f7 Phil Davis
		}
272 26e3ca70 sullrich
273 8f8682f7 Phil Davis
		if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
274
			$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
275
		}
276 e680b2f9 Renato Botelho
277
		if (isset($config['captiveportal']) && is_array($config['captiveportal'])) {
278
			$deftime = 7200; // Default value if it's empty
279 8f8682f7 Phil Davis
			if (is_numeric($_POST['deftime'])) {
280 e680b2f9 Renato Botelho
				$deftime = $_POST['deftime'];
281 8f8682f7 Phil Davis
			}
282 e680b2f9 Renato Botelho
283
			foreach ($config['captiveportal'] as $cpZone => $cpdata) {
284 8f8682f7 Phil Davis
				if (!isset($cpdata['enable'])) {
285 e680b2f9 Renato Botelho
					continue;
286 8f8682f7 Phil Davis
				}
287
				if (!isset($cpdata['timeout']) || !is_numeric($cpdata['timeout'])) {
288 e680b2f9 Renato Botelho
					continue;
289 8f8682f7 Phil Davis
				}
290 e680b2f9 Renato Botelho
				$cp_ifs = explode(',', $cpdata['interface']);
291 8f8682f7 Phil Davis
				if (!in_array($if, $cp_ifs)) {
292 e680b2f9 Renato Botelho
					continue;
293 8f8682f7 Phil Davis
				}
294
				if ($cpdata['timeout'] > $deftime) {
295 e680b2f9 Renato Botelho
					$input_errors[] = sprintf(gettext(
296 0a8a90f7 Phil Davis
						'The Captive Portal zone (%1$s) has Hard Timeout parameter set to a value bigger than Default lease time (%2$s).'), $cpZone, $deftime);
297 8f8682f7 Phil Davis
				}
298 e680b2f9 Renato Botelho
			}
299
		}
300
301 8f8682f7 Phil Davis
		if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
302 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
303 8f8682f7 Phil Davis
		}
304
		if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain']))) {
305 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
306 8f8682f7 Phil Davis
		}
307
		if (($_POST['ddnsdomain'] && !is_ipaddrv4($_POST['ddnsdomainprimary']))) {
308 87019fc4 Andres Petralli
			$input_errors[] = gettext("A valid primary domain name server IP address must be specified for the dynamic domain name.");
309 8f8682f7 Phil Davis
		}
310 87019fc4 Andres Petralli
		if (($_POST['ddnsdomainkey'] && !$_POST['ddnsdomainkeyname']) ||
311 6e3488e9 Phil Davis
		    ($_POST['ddnsdomainkeyname'] && !$_POST['ddnsdomainkey'])) {
312 87019fc4 Andres Petralli
			$input_errors[] = gettext("You must specify both a valid domain key and key name.");
313 8f8682f7 Phil Davis
		}
314 42a3cbab Pierre POMES
		if ($_POST['domainsearchlist']) {
315 8f8682f7 Phil Davis
			$domain_array = preg_split("/[ ;]+/", $_POST['domainsearchlist']);
316 42a3cbab Pierre POMES
			foreach ($domain_array as $curdomain) {
317
				if (!is_domain($curdomain)) {
318
					$input_errors[] = gettext("A valid domain search list must be specified.");
319
					break;
320
				}
321
			}
322
		}
323 1f1a08c8 jim-p
324
		// Validate MACs
325 8f8682f7 Phil Davis
		if (!empty($_POST['mac_allow']) && !validate_partial_mac_list($_POST['mac_allow'])) {
326 1f1a08c8 jim-p
			$input_errors[] = gettext("If you specify a mac allow list, it must contain only valid partial MAC addresses.");
327 8f8682f7 Phil Davis
		}
328
		if (!empty($_POST['mac_deny']) && !validate_partial_mac_list($_POST['mac_deny'])) {
329 1f1a08c8 jim-p
			$input_errors[] = gettext("If you specify a mac deny list, it must contain only valid partial MAC addresses.");
330 8f8682f7 Phil Davis
		}
331 1f1a08c8 jim-p
332 8f8682f7 Phil Davis
		if (($_POST['ntp1'] && !is_ipaddrv4($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv4($_POST['ntp2']))) {
333 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the primary/secondary NTP servers.");
334 8f8682f7 Phil Davis
		}
335
		if (($_POST['domain'] && !is_domain($_POST['domain']))) {
336 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
337 8f8682f7 Phil Davis
		}
338
		if ($_POST['tftp'] && !is_ipaddrv4($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
339 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address or hostname must be specified for the TFTP server.");
340 8f8682f7 Phil Davis
		}
341
		if (($_POST['nextserver'] && !is_ipaddrv4($_POST['nextserver']))) {
342 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("A valid IP address must be specified for the network boot server.");
343 8f8682f7 Phil Davis
		}
344 2c75b451 sullrich
345 8f8682f7 Phil Davis
		if (gen_subnet($ifcfgip, $ifcfgsn) == $_POST['range_from']) {
346 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("You cannot use the network address in the starting subnet range.");
347 8f8682f7 Phil Davis
		}
348
		if (gen_subnet_max($ifcfgip, $ifcfgsn) == $_POST['range_to']) {
349 40ad67e0 Rafael Lucas
			$input_errors[] = gettext("You cannot use the broadcast address in the ending subnet range.");
350 8f8682f7 Phil Davis
		}
351 e9f147c8 Scott Ullrich
352 2c75b451 sullrich
		// Disallow a range that includes the virtualip
353 7dfa60fa Ermal Lu?i
		if (is_array($config['virtualip']['vip'])) {
354 8f8682f7 Phil Davis
			foreach ($config['virtualip']['vip'] as $vip) {
355
				if ($vip['interface'] == $if) {
356
					if ($vip['subnet'] && is_inrange_v4($vip['subnet'], $_POST['range_from'], $_POST['range_to'])) {
357
						$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IP address %s."), $vip['subnet']);
358
					}
359
				}
360 7dfa60fa Ermal Lu?i
			}
361 2c75b451 sullrich
		}
362
363 073a2697 jim-p
		$noip = false;
364 8f8682f7 Phil Davis
		if (is_array($a_maps)) {
365
			foreach ($a_maps as $map) {
366
				if (empty($map['ipaddr'])) {
367 2c7497cb Scott Ullrich
					$noip = true;
368 8f8682f7 Phil Davis
				}
369
			}
370
		}
371 b5f6e690 Stephen Beaver
372 8f8682f7 Phil Davis
		if ($_POST['staticarp'] && $noip) {
373 4bb7c0d1 bruno
			$input_errors[] = gettext("Cannot enable static ARP when you have static map entries without IP addresses. Ensure all static maps have IP addresses and try again.");
374 8f8682f7 Phil Davis
		}
375 073a2697 jim-p
376 8f8682f7 Phil Davis
		if (is_array($pconfig['numberoptions']['item'])) {
377 678dfd0f Erik Fonnesbeck
			foreach ($pconfig['numberoptions']['item'] as $numberoption) {
378 25d66c61 NewEraCracker
				$numberoption_value = base64_decode($numberoption['value']);
379
				if ($numberoption['type'] == 'text' && strstr($numberoption_value, '"')) {
380 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Text type cannot include quotation marks.");
381 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'string' && !preg_match('/^"[^"]*"$/', $numberoption_value) && !preg_match('/^[0-9a-f]{2}(?:\:[0-9a-f]{2})*$/i', $numberoption_value)) {
382 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");
383 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'boolean' && $numberoption_value != 'true' && $numberoption_value != 'false' && $numberoption_value != 'on' && $numberoption_value != 'off') {
384 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Boolean type must be true, false, on, or off.");
385 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'unsigned integer 8' && (!is_numeric($numberoption_value) || $numberoption_value < 0 || $numberoption_value > 255)) {
386 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Unsigned 8-bit integer type must be a number in the range 0 to 255.");
387 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'unsigned integer 16' && (!is_numeric($numberoption_value) || $numberoption_value < 0 || $numberoption_value > 65535)) {
388 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Unsigned 16-bit integer type must be a number in the range 0 to 65535.");
389 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'unsigned integer 32' && (!is_numeric($numberoption_value) || $numberoption_value < 0 || $numberoption_value > 4294967295)) {
390 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Unsigned 32-bit integer type must be a number in the range 0 to 4294967295.");
391 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'signed integer 8' && (!is_numeric($numberoption_value) || $numberoption_value < -128 || $numberoption_value > 127)) {
392 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Signed 8-bit integer type must be a number in the range -128 to 127.");
393 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'signed integer 16' && (!is_numeric($numberoption_value) || $numberoption_value < -32768 || $numberoption_value > 32767)) {
394 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Signed 16-bit integer type must be a number in the range -32768 to 32767.");
395 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'signed integer 32' && (!is_numeric($numberoption_value) || $numberoption_value < -2147483648 || $numberoption_value > 2147483647)) {
396 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("Signed 32-bit integer type must be a number in the range -2147483648 to 2147483647.");
397 25d66c61 NewEraCracker
				} else if ($numberoption['type'] == 'ip-address' && !is_ipaddrv4($numberoption_value) && !is_hostname($numberoption_value)) {
398 678dfd0f Erik Fonnesbeck
					$input_errors[] = gettext("IP address or host type must be an IP address or host name.");
399 8f8682f7 Phil Davis
				}
400 678dfd0f Erik Fonnesbeck
			}
401
		}
402
403 5b237745 Scott Ullrich
		if (!$input_errors) {
404
			/* make sure the range lies within the current subnet */
405 96033063 Erik Fonnesbeck
			$subnet_start = ip2ulong(long2ip32(ip2long($ifcfgip) & gen_subnet_mask_long($ifcfgsn)));
406
			$subnet_end = ip2ulong(long2ip32(ip2long($ifcfgip) | (~gen_subnet_mask_long($ifcfgsn))));
407 e9f147c8 Scott Ullrich
408 8f8682f7 Phil Davis
			if (ip2ulong($_POST['range_from']) > ip2ulong($_POST['range_to'])) {
409 40ad67e0 Rafael Lucas
				$input_errors[] = gettext("The range is invalid (first element higher than second element).");
410 8f8682f7 Phil Davis
			}
411 e9f147c8 Scott Ullrich
412 ec513fa9 stilez
			if (ip2ulong($_POST['range_from']) < $subnet_start || ip2ulong($_POST['range_to']) > $subnet_end) {
413
				$input_errors[] = gettext("The specified range lies outside of the current subnet.");
414
			}
415
416 f657f5e1 Renato Botelho
			if (is_numeric($pool) || ($act == "newpool")) {
417 e7940d2e Phil Davis
				if (!((ip2ulong($_POST['range_from']) > ip2ulong($config['dhcpd'][$if]['range']['to'])) ||
418
				      (ip2ulong($_POST['range_to']) < ip2ulong($config['dhcpd'][$if]['range']['from'])))) {
419 f657f5e1 Renato Botelho
					$input_errors[] = gettext("The specified range must not be within the DHCP range for this interface.");
420 8f8682f7 Phil Davis
				}
421 f657f5e1 Renato Botelho
			}
422
423
			foreach ($a_pools as $id => $p) {
424 8f8682f7 Phil Davis
				if (is_numeric($pool) && ($id == $pool)) {
425 f657f5e1 Renato Botelho
					continue;
426 8f8682f7 Phil Davis
				}
427 f657f5e1 Renato Botelho
428 e7940d2e Phil Davis
				if (!((ip2ulong($_POST['range_from']) > ip2ulong($p['range']['to'])) ||
429
				      (ip2ulong($_POST['range_to']) < ip2ulong($p['range']['from'])))) {
430 f657f5e1 Renato Botelho
					$input_errors[] = gettext("The specified range must not be within the range configured on a DHCP pool for this interface.");
431
					break;
432
				}
433
			}
434 cba980f6 jim-p
435 5b237745 Scott Ullrich
			/* make sure that the DHCP Relay isn't enabled on this interface */
436 8f8682f7 Phil Davis
			if (isset($config['dhcrelay']['enable']) && (stristr($config['dhcrelay']['interface'], $if) !== false)) {
437
				$input_errors[] = sprintf(gettext("You must disable the DHCP relay on the %s interface before enabling the DHCP server."), $iflist[$if]);
438
			}
439 630d7025 jim-p
440
			$dynsubnet_start = ip2ulong($_POST['range_from']);
441
			$dynsubnet_end = ip2ulong($_POST['range_to']);
442 f02f0675 Erik Fonnesbeck
			if (is_array($a_maps)) {
443
				foreach ($a_maps as $map) {
444 8f8682f7 Phil Davis
					if (empty($map['ipaddr'])) {
445 f02f0675 Erik Fonnesbeck
						continue;
446 8f8682f7 Phil Davis
					}
447 e7940d2e Phil Davis
					if ((ip2ulong($map['ipaddr']) >= $dynsubnet_start) &&
448
					    (ip2ulong($map['ipaddr']) <= $dynsubnet_end)) {
449 f02f0675 Erik Fonnesbeck
						$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
450
						break;
451
					}
452 630d7025 jim-p
				}
453
			}
454 5b237745 Scott Ullrich
		}
455
	}
456
457
	if (!$input_errors) {
458 cba980f6 jim-p
		if (!is_numeric($pool)) {
459
			if ($act == "newpool") {
460
				$dhcpdconf = array();
461
			} else {
462 8f8682f7 Phil Davis
				if (!is_array($config['dhcpd'][$if])) {
463 cba980f6 jim-p
					$config['dhcpd'][$if] = array();
464 8f8682f7 Phil Davis
				}
465 cba980f6 jim-p
				$dhcpdconf = $config['dhcpd'][$if];
466
			}
467
		} else {
468
			if (is_array($a_pools[$pool])) {
469
				$dhcpdconf = $a_pools[$pool];
470
			} else {
471
				// Someone specified a pool but it doesn't exist. Punt.
472
				header("Location: services_dhcp.php");
473
				exit;
474
			}
475
		}
476 8f8682f7 Phil Davis
		if (!is_array($dhcpdconf['range'])) {
477 cba980f6 jim-p
			$dhcpdconf['range'] = array();
478 8f8682f7 Phil Davis
		}
479 cba980f6 jim-p
480 6c124212 Phil Davis
		$dhcpd_enable_changed = false;
481
482 cba980f6 jim-p
		// Global Options
483
		if (!is_numeric($pool) && !($act == "newpool")) {
484 6c124212 Phil Davis
			$old_dhcpd_enable = isset($dhcpdconf['enable']);
485
			$new_dhcpd_enable = ($_POST['enable']) ? true : false;
486
			if ($old_dhcpd_enable != $new_dhcpd_enable) {
487
				/* DHCP has been enabled or disabled. The pf ruleset will need to be rebuilt to allow or disallow DHCP. */
488
				$dhcpd_enable_changed = true;
489
			}
490 b5f6e690 Stephen Beaver
491 6c124212 Phil Davis
			$dhcpdconf['enable'] = $new_dhcpd_enable;
492 cba980f6 jim-p
			$dhcpdconf['staticarp'] = ($_POST['staticarp']) ? true : false;
493
			$previous = $dhcpdconf['failover_peerip'];
494 b5f6e690 Stephen Beaver
			if ($previous != $_POST['failover_peerip']) {
495 cba980f6 jim-p
				mwexec("/bin/rm -rf /var/dhcpd/var/db/*");
496 8f8682f7 Phil Davis
			}
497 b5f6e690 Stephen Beaver
498 cba980f6 jim-p
			$dhcpdconf['failover_peerip'] = $_POST['failover_peerip'];
499 466aae83 Phil Davis
			// dhcpleaseinlocaltime is global to all interfaces. So update the setting on all interfaces.
500
			foreach ($config['dhcpd'] as &$dhcpdifitem) {
501
				$dhcpdifitem['dhcpleaseinlocaltime'] = $_POST['dhcpleaseinlocaltime'];
502
			}
503 ee1fb205 jim-p
		} else {
504
			// Options that exist only in pools
505
			$dhcpdconf['descr'] = $_POST['descr'];
506 cba980f6 jim-p
		}
507
508
		// Options that can be global or per-pool.
509
		$dhcpdconf['range']['from'] = $_POST['range_from'];
510
		$dhcpdconf['range']['to'] = $_POST['range_to'];
511
		$dhcpdconf['defaultleasetime'] = $_POST['deftime'];
512
		$dhcpdconf['maxleasetime'] = $_POST['maxtime'];
513
		$dhcpdconf['netmask'] = $_POST['netmask'];
514
515
		unset($dhcpdconf['winsserver']);
516 8f8682f7 Phil Davis
		if ($_POST['wins1']) {
517 cba980f6 jim-p
			$dhcpdconf['winsserver'][] = $_POST['wins1'];
518 8f8682f7 Phil Davis
		}
519
		if ($_POST['wins2']) {
520 cba980f6 jim-p
			$dhcpdconf['winsserver'][] = $_POST['wins2'];
521 8f8682f7 Phil Davis
		}
522 4cab31d0 Scott Ullrich
523 cba980f6 jim-p
		unset($dhcpdconf['dnsserver']);
524 8f8682f7 Phil Davis
		if ($_POST['dns1']) {
525 cba980f6 jim-p
			$dhcpdconf['dnsserver'][] = $_POST['dns1'];
526 8f8682f7 Phil Davis
		}
527
		if ($_POST['dns2']) {
528 cba980f6 jim-p
			$dhcpdconf['dnsserver'][] = $_POST['dns2'];
529 8f8682f7 Phil Davis
		}
530
		if ($_POST['dns3']) {
531 3b5707db Phil Davis
			$dhcpdconf['dnsserver'][] = $_POST['dns3'];
532 8f8682f7 Phil Davis
		}
533
		if ($_POST['dns4']) {
534 3b5707db Phil Davis
			$dhcpdconf['dnsserver'][] = $_POST['dns4'];
535 8f8682f7 Phil Davis
		}
536 cba980f6 jim-p
537
		$dhcpdconf['gateway'] = $_POST['gateway'];
538
		$dhcpdconf['domain'] = $_POST['domain'];
539
		$dhcpdconf['domainsearchlist'] = $_POST['domainsearchlist'];
540
		$dhcpdconf['denyunknown'] = ($_POST['denyunknown']) ? true : false;
541 3475eb04 Andrew Pilloud
		$dhcpdconf['nonak'] = ($_POST['nonak']) ? true : false;
542 cba980f6 jim-p
		$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 464358b4 Phil Davis
	print_apply_box(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 3475eb04 Andrew Pilloud
$section->addInput(new Form_Checkbox(
781
	'nonak',
782
	'Ignore denied clients',
783
	'Denied clients will be ignored rather than rejected.',
784
	$pconfig['nonak']
785
));
786
787
788 b5f6e690 Stephen Beaver
if (is_numeric($pool) || ($act == "newpool")) {
789
	$section->addInput(new Form_Input(
790
		'descr',
791
		'Pool Description',
792
		'text',
793
		$pconfig['descr']
794
	));
795
}
796 6c23757b Martin Fuchs
797 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
798
	'Subnet',
799
	gen_subnet($ifcfgip, $ifcfgsn)
800
));
801 4e9cd828 Seth Mos
802 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
803
	'Subnet mask',
804
	gen_subnet_mask($ifcfgsn)
805
));
806 5b237745 Scott Ullrich
807 8a73f407 Stephen Beaver
// Compose a string to display the required address ranges
808 c18ba6bf Phil Davis
$range_from = ip2long(gen_subnetv4($ifcfgip, $ifcfgsn));
809 b5f6e690 Stephen Beaver
$range_from++;
810
811 c18ba6bf Phil Davis
$range_to = ip2long(gen_subnetv4_max($ifcfgip, $ifcfgsn));
812 b5f6e690 Stephen Beaver
$range_to--;
813
814
$rangestr = long2ip32($range_from) . ' - ' . long2ip32($range_to);
815
816
if (is_numeric($pool) || ($act == "newpool")) {
817 4bb7c0d1 bruno
	$rangestr .= '<br />' . gettext('In-use DHCP Pool Ranges:');
818 b5f6e690 Stephen Beaver
	if (is_array($config['dhcpd'][$if]['range'])) {
819
		$rangestr .= '<br />' . $config['dhcpd'][$if]['range']['from'] . ' - ' . $config['dhcpd'][$if]['range']['to'];
820 3d7b7757 Chris Buechler
	}
821 b5f6e690 Stephen Beaver
822
	foreach ($a_pools as $p) {
823
		if (is_array($p['range'])) {
824
			$rangestr .= '<br />' . $p['range']['from'] . ' - ' . $p['range']['to'];
825 8f8682f7 Phil Davis
		}
826 934240ef Ermal Luçi
	}
827 b5f6e690 Stephen Beaver
}
828
829
$section->addInput(new Form_StaticText(
830
	'Available range',
831
	$rangestr
832
));
833
834
if ($is_olsr_enabled) {
835
	$section->addInput(new Form_Select(
836
		'netmask',
837
		'Subnet mask',
838
		$pconfig['netmask'],
839
		array_combine(range(32, 1, -1), range(32, 1, -1))
840
	));
841
}
842
843
$group = new Form_Group('Range');
844
845
$group->add(new Form_IpAddress(
846
	'range_from',
847
	null,
848
	$pconfig['range_from']
849
))->setHelp('From');
850
851
$group->add(new Form_IpAddress(
852
	'range_to',
853
	null,
854
	$pconfig['range_to']
855
))->setHelp('To');
856
857
$section->add($group);
858
859
$form->add($section);
860
861
if (!is_numeric($pool) && !($act == "newpool")) {
862
	$section = new Form_Section('Additional pools');
863
864
	$btnaddpool = new Form_Button(
865
		'btnaddpool',
866
		'Add pool',
867
		'services_dhcp.php?if=' . htmlspecialchars($if) . '&act=newpool'
868
	);
869
870
	$section->addInput(new Form_StaticText(
871
		'Add',
872
		$btnaddpool
873
	))->setHelp('If you need additional pools of addresses inside of this subnet outside the above Range, they may be specified here');
874
875
	if (is_array($a_pools)) {
876
		$section->addInput(new Form_StaticText(
877
			null,
878
			build_pooltable()
879
		));
880 f0cdf141 Scott Ullrich
	}
881 b5f6e690 Stephen Beaver
882
	$form->add($section);
883
}
884
885
$section = new Form_Section('Servers');
886
887
$section->addInput(new Form_IpAddress(
888
	'wins1',
889
	'WINS servers',
890
	$pconfig['wins1']
891
))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'WINS Server 1');
892
893
$section->addInput(new Form_IpAddress(
894
	'wins2',
895
	null,
896
	$pconfig['wins2']
897
))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'WINS Server 2');
898
899 6e3488e9 Phil Davis
for ($idx=1; $idx<=4; $idx++) {
900 b5f6e690 Stephen Beaver
	$section->addInput(new Form_IpAddress(
901
		'dns' . $idx,
902
		($idx == 1) ? 'DNS servers':null,
903
		$pconfig['dns' . $idx]
904
	))->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':'');
905
}
906
907
$form->add($section);
908
909
$section = new Form_Section('Other options');
910
911
$section->addInput(new Form_IpAddress(
912
	'gateway',
913
	'Gateway',
914
	$pconfig['gateway']
915
))->setPattern('[.a-zA-Z0-9_]+')
916
  ->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');
917
918
$section->addInput(new Form_Input(
919
	'domain',
920
	'Domain name',
921
	'text',
922
	$pconfig['domain']
923
))->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');
924
925
$section->addInput(new Form_Input(
926
	'domainsearchlist',
927
	'Domain search list',
928
	'text',
929
	$pconfig['domainsearchlist']
930
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator');
931
932
$section->addInput(new Form_Input(
933
	'deftime',
934
	'Default lease time',
935
	'number',
936
	$pconfig['deftime']
937
))->setHelp('This is used for clients that do not ask for a specific expiration time. The default is 7200 seconds');
938
939
$section->addInput(new Form_Input(
940
	'maxtime',
941
	'Maximum lease time',
942
	'number',
943
	$pconfig['maxtime']
944
))->setHelp('This is the maximum lease time for clients that ask for a specific expiration time. The default is 86400 seconds');
945
946
if (!is_numeric($pool) && !($act == "newpool")) {
947
	$section->addInput(new Form_IpAddress(
948
		'failover_peerip',
949
		'Failover peer IP',
950
		$pconfig['failover_peerip']
951 af8f79b1 Chris Buechler
	))->setHelp('Leave blank to disable. Enter the interface IP address of the other machine. Machines must be using CARP. ' .
952 4c1284c6 NOYB
				'Interface\'s advskew determines whether the DHCPd process is Primary or Secondary. Ensure one machine\'s advskew &lt; 20 (and the other is &gt; 20).');
953 b5f6e690 Stephen Beaver
}
954
955
if (!is_numeric($pool) && !($act == "newpool")) {
956
	$section->addInput(new Form_Checkbox(
957
		'staticarp',
958
		'Static ARP',
959
		'Enable Static ARP entries',
960
		$pconfig['staticarp']
961 0c8d2784 Chris Buechler
	))->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 interface.');
962 b5f6e690 Stephen Beaver
963
	$section->addInput(new Form_Checkbox(
964
		'dhcpleaseinlocaltime',
965
		'Time format change',
966
		'Change DHCP display lease time from UTC to local time',
967
		$pconfig['dhcpleaseinlocaltime']
968
	))->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.' .
969
				' This will be used for all DHCP interfaces lease time');
970 18d316a5 heper
	$section->addInput(new Form_Checkbox(
971
		'statsgraph',
972 61237194 Chris Buechler
		'Statistics graphs',
973
		'Enable RRD statistics graphs',
974 18d316a5 heper
		$pconfig['statsgraph']
975 61237194 Chris Buechler
	))->setHelp('Enable this to add DHCP leases statistics to the RRD graphs. Disabled by default.');
976 b5f6e690 Stephen Beaver
}
977
978
// DDNS
979
$btnadv = new Form_Button(
980
	'btnadvdns',
981
	'Advanced'
982
);
983
984 ef2936e6 Stephen Beaver
$btnadv->removeClass('btn-primary')->addClass('btn-info btn-sm');
985 b5f6e690 Stephen Beaver
986
$section->addInput(new Form_StaticText(
987
	'Dynamic DNS',
988
	$btnadv
989
));
990
991
$section->addInput(new Form_Checkbox(
992
	'ddnsupdate',
993
	null,
994
	'Enable registration of DHCP client names in DNS',
995
	$pconfig['ddnsupdate']
996
));
997
998
$section->addInput(new Form_Input(
999
	'ddnsdomain',
1000
	'DDNS Domain',
1001 e8da0bcd Jeremy Porter
	'text',
1002 b5f6e690 Stephen Beaver
	$pconfig['ddnsdomain']
1003
))->setHelp('Leave blank to disable dynamic DNS registration.' . '<br />' .
1004
			'Enter the dynamic DNS domain which will be used to register client names in the DNS server.');
1005
1006
$section->addInput(new Form_IpAddress(
1007
	'ddnsdomainprimary',
1008
	'Primary DDNS address',
1009
	$pconfig['ddnsdomainprimary']
1010
))->setHelp('Primary domain name server IP address for the dynamic domain name');
1011
1012
$section->addInput(new Form_Input(
1013
	'ddnsdomainkeyname',
1014
	'DNS Domain key',
1015
	'text',
1016
	$pconfig['ddnsdomainkeyname']
1017
))->setHelp('Dynamic DNS domain key name which will be used to register client names in the DNS server');
1018
1019
$section->addInput(new Form_Input(
1020
	'ddnsdomainkey',
1021
	'DNS Domain key secret',
1022
	'text',
1023
	$pconfig['ddnsdomainkey']
1024
))->setHelp('Dynamic DNS domain key secret which will be used to register client names in the DNS server');
1025
1026
// Advanced MAC
1027
$btnadv = new Form_Button(
1028
	'btnadvmac',
1029
	'Advanced'
1030
);
1031
1032 ef2936e6 Stephen Beaver
$btnadv->removeClass('btn-primary')->addClass('btn-info btn-sm');
1033 b5f6e690 Stephen Beaver
1034
$section->addInput(new Form_StaticText(
1035
	'MAC address control',
1036
	$btnadv
1037
));
1038
1039
$section->addInput(new Form_Input(
1040
	'mac_allow',
1041 ef2936e6 Stephen Beaver
	'MAC Allow',
1042 b5f6e690 Stephen Beaver
	'text',
1043
	$pconfig['mac_allow']
1044
))->setHelp('List of partial MAC addresses to allow, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1045
1046
$section->addInput(new Form_Input(
1047
	'mac_deny',
1048 ef2936e6 Stephen Beaver
	'MAC Deny',
1049 b5f6e690 Stephen Beaver
	'text',
1050
	$pconfig['mac_deny']
1051
))->setHelp('List of partial MAC addresses to deny access, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1052
1053
// Advanced NTP
1054
$btnadv = new Form_Button(
1055
	'btnadvntp',
1056
	'Advanced'
1057
);
1058
1059 ef2936e6 Stephen Beaver
$btnadv->removeClass('btn-primary')->addClass('btn-info btn-sm');
1060 b5f6e690 Stephen Beaver
1061
$section->addInput(new Form_StaticText(
1062 ff3da1e7 Stephen Beaver
	'NTP',
1063 b5f6e690 Stephen Beaver
	$btnadv
1064
));
1065
1066
$section->addInput(new Form_IpAddress(
1067
	'ntp1',
1068 ff3da1e7 Stephen Beaver
	'NTP Server 1',
1069 b5f6e690 Stephen Beaver
	$pconfig['ntp1']
1070 ff3da1e7 Stephen Beaver
));
1071 b5f6e690 Stephen Beaver
1072
$section->addInput(new Form_IpAddress(
1073
	'ntp2',
1074 ff3da1e7 Stephen Beaver
	'NTP Server 2',
1075 b5f6e690 Stephen Beaver
	$pconfig['ntp2']
1076 ff3da1e7 Stephen Beaver
));
1077 b5f6e690 Stephen Beaver
1078
// Advanced TFTP
1079
$btnadv = new Form_Button(
1080
	'btnadvtftp',
1081
	'Advanced'
1082
);
1083
1084 ef2936e6 Stephen Beaver
$btnadv->removeClass('btn-primary')->addClass('btn-info btn-sm');
1085 b5f6e690 Stephen Beaver
1086
$section->addInput(new Form_StaticText(
1087 ff3da1e7 Stephen Beaver
	'TFTP',
1088 b5f6e690 Stephen Beaver
	$btnadv
1089
));
1090
1091
$section->addInput(new Form_IpAddress(
1092
	'tftp',
1093 ff3da1e7 Stephen Beaver
	'TFTP Server',
1094 b5f6e690 Stephen Beaver
	$pconfig['tftp']
1095
))->setHelp('Leave blank to disable.  Enter a full hostname or IP for the TFTP server')->setPattern('[.a-zA-Z0-9_]+');
1096
1097
// Advanced LDAP
1098
$btnadv = new Form_Button(
1099
	'btnadvldap',
1100
	'Advanced'
1101
);
1102
1103 ef2936e6 Stephen Beaver
$btnadv->removeClass('btn-primary')->addClass('btn-info btn-sm');
1104 b5f6e690 Stephen Beaver
1105
$section->addInput(new Form_StaticText(
1106 ff3da1e7 Stephen Beaver
	'LDAP',
1107 b5f6e690 Stephen Beaver
	$btnadv
1108
));
1109
1110
$section->addInput(new Form_Input(
1111
	'ldap',
1112 ff3da1e7 Stephen Beaver
	'LDAP Server URI',
1113 b5f6e690 Stephen Beaver
	'text',
1114
	$pconfig['ldap']
1115
))->setHelp('Leave blank to disable. Enter a full URI for the LDAP server in the form ldap://ldap.example.com/dc=example,dc=com ');
1116
1117 ef2936e6 Stephen Beaver
$form->add($section);
1118 b5f6e690 Stephen Beaver
1119
// Advanced Additional options
1120
$btnadv = new Form_Button(
1121
	'btnadvopts',
1122
	'Advanced'
1123
);
1124
1125 ef2936e6 Stephen Beaver
$btnadv->removeClass('btn-primary')->addClass('btn-info btn-sm');
1126 b5f6e690 Stephen Beaver
1127
$section->addInput(new Form_StaticText(
1128
	'Additional BOOTP/DHCP Options',
1129
	$btnadv
1130
));
1131
1132
$section = new Form_Section('Additional BOOTP/DHCP Options');
1133
$section->addClass('adnlopts');
1134
1135
$section->addInput(new Form_StaticText(
1136
	null,
1137 0a8a90f7 Phil Davis
	'<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.') . ' ' .
1138
	sprintf(gettext('For a list of available options please visit this %1$s URL%2$s'), '<a href="http://www.iana.org/assignments/bootp-dhcp-parameters/" target="_blank">', '</a></div>')
1139 b5f6e690 Stephen Beaver
));
1140
1141 6e3488e9 Phil Davis
if (!$pconfig['numberoptions']) {
1142 b5f6e690 Stephen Beaver
	$pconfig['numberoptions']['item']  = array(array('number' => '', 'type' => 'text', 'value' => ''));
1143
}
1144
1145
$customitemtypes = array(
1146
	'text' => gettext('Text'), 'string' => gettext('String'), 'boolean' => gettext('Boolean'),
1147
	'unsigned integer 8' => gettext('Unsigned 8-bit integer'), 'unsigned integer 16' => gettext('Unsigned 16-bit integer'), 'unsigned integer 32' => gettext('Unsigned 32-bit integer'),
1148
	'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')
1149
);
1150
1151
$numrows = count($item) -1;
1152
$counter = 0;
1153
1154
$numrows = count($pconfig['numberoptions']['item']) -1;
1155
1156
foreach ($pconfig['numberoptions']['item'] as $item) {
1157
	$number = $item['number'];
1158
	$itemtype = $item['type'];
1159 65cce9d7 Renato Botelho
	$value = base64_decode($item['value']);
1160 b5f6e690 Stephen Beaver
1161
	$group = new Form_Group(($counter == 0) ? 'Option':null);
1162
	$group->addClass('repeatable');
1163
1164
	$group->add(new Form_Input(
1165
		'number' . $counter,
1166
		null,
1167
		'text',
1168
		$number
1169
	))->setHelp($numrows == $counter ? 'Number':null);
1170
1171
1172
	$group->add(new Form_Select(
1173
		'itemtype' . $counter,
1174
		null,
1175
		$itemtype,
1176
		$customitemtypes
1177 8a73f407 Stephen Beaver
	))->setWidth(3)->setHelp($numrows == $counter ? 'Type':null);
1178 b5f6e690 Stephen Beaver
1179
	$group->add(new Form_Input(
1180
		'value' . $counter,
1181
		null,
1182
		'text',
1183
		$value
1184
	))->setHelp($numrows == $counter ? 'Value':null);
1185
1186
	$group->add(new Form_Button(
1187
		'deleterow' . $counter,
1188
		'Delete'
1189
	))->removeClass('btn-primary')->addClass('btn-warning');
1190
1191
	$section->add($group);
1192
1193
	$counter++;
1194
}
1195
1196
$section->addInput(new Form_Button(
1197
	'addrow',
1198
	'Add'
1199
))->removeClass('btn-primary')->addClass('btn-success');
1200
1201
$form->add($section);
1202
1203 5dfc79c9 Stephen Beaver
if ($pconfig['netboot']) {
1204
	$sectate = COLLAPSIBLE|SEC_OPEN;
1205
} else {
1206
	$sectate = COLLAPSIBLE|SEC_CLOSED;
1207
}
1208
$section = new Form_Section("Network booting", nwkbootsec, $sectate);
1209
1210
$section->addInput(new Form_Checkbox(
1211
	'netboot',
1212
	'Enable',
1213
	'Enables network booting',
1214
	$pconfig['netboot']
1215
));
1216
1217
$section->addInput(new Form_IpAddress(
1218
	'nextserver',
1219
	'Next Server',
1220
	$pconfig['nextserver']
1221
))->setHelp('Enter the IP address of the next server');
1222
1223
$section->addInput(new Form_Input(
1224
	'filename',
1225
	'Default BIOS file name',
1226
	'text',
1227
	$pconfig['filename']
1228
));
1229
1230
$section->addInput(new Form_Input(
1231
	'filename32',
1232
	'UEFI 32 bit file name',
1233
	'text',
1234
	$pconfig['filename32']
1235
));
1236
1237
$section->addInput(new Form_Input(
1238
	'filename64',
1239
	'UEFI 64 bit file name',
1240
	'text',
1241
	$pconfig['filename64']
1242
))->setHelp('You need both a filename and a boot server configured for this to work! ' .
1243
			'You will need all three filenames and a boot server configured for UEFI to work! ');
1244
1245
$section->addInput(new Form_Input(
1246
	'rootpath',
1247
	'Root path',
1248
	'text',
1249
	$pconfig['rootpath']
1250
))->setHelp('string-format: iscsi:(servername):(protocol):(port):(LUN):targetname ');
1251
1252
$form->add($section);
1253
1254 b5f6e690 Stephen Beaver
if ($act == "newpool") {
1255
	$form->addGlobal(new Form_Input(
1256
		'act',
1257
		null,
1258
		'hidden',
1259
		'newpool'
1260
	));
1261
}
1262
1263
if (is_numeric($pool)) {
1264
	$form->addGlobal(new Form_Input(
1265
		'pool',
1266
		null,
1267
		'hidden',
1268
		$pool
1269
	));
1270
}
1271
1272
$form->addGlobal(new Form_Input(
1273
	'if',
1274
	null,
1275
	'hidden',
1276
	$if
1277
));
1278
1279
print($form);
1280
1281
// DHCP Static Mappings table
1282
1283
if (!is_numeric($pool) && !($act == "newpool")) {
1284 de792e62 jim-p
?>
1285 b5f6e690 Stephen Beaver
1286
<div class="panel panel-default">
1287 7683c990 Chris Buechler
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCP Static Mappings for this interface")?></h2></div>
1288 b5f6e690 Stephen Beaver
	<div class="table-responsive">
1289
			<table class="table table-striped table-hover table-condensed">
1290
				<thead>
1291
					<tr>
1292
						<th><?=gettext("Static ARP")?></th>
1293
						<th><?=gettext("MAC address")?></th>
1294
						<th><?=gettext("IP address")?></th>
1295
						<th><?=gettext("Hostname")?></th>
1296
						<th><?=gettext("Description")?></th>
1297
						<th></th>
1298
					</tr>
1299
				</thead>
1300 8f8682f7 Phil Davis
<?php
1301 b5f6e690 Stephen Beaver
	if (is_array($a_maps)) {
1302
		$i = 0;
1303 8f8682f7 Phil Davis
?>
1304 b5f6e690 Stephen Beaver
				<tbody>
1305 8f8682f7 Phil Davis
<?php
1306 b5f6e690 Stephen Beaver
		foreach ($a_maps as $mapent) {
1307 8f8682f7 Phil Davis
?>
1308 b5f6e690 Stephen Beaver
					<tr>
1309
						<td align="center" ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1310
							<?php if (isset($mapent['arp_table_static_entry'])): ?>
1311 1b7379f9 Jared Dillard
								<i class="fa fa-check"></i>
1312 b5f6e690 Stephen Beaver
							<?php endif; ?>
1313
						</td>
1314
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1315
							<?=htmlspecialchars($mapent['mac'])?>
1316
						</td>
1317
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1318
							<?=htmlspecialchars($mapent['ipaddr'])?>
1319
						</td>
1320
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1321
							<?=htmlspecialchars($mapent['hostname'])?>
1322
						</td>
1323
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1324
							<?=htmlspecialchars($mapent['descr'])?>
1325
						</td>
1326
						<td>
1327 9a6a8329 heper
							<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>"	href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>"></a>
1328 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>
1329 b5f6e690 Stephen Beaver
						</td>
1330
					</tr>
1331 8f8682f7 Phil Davis
<?php
1332 b5f6e690 Stephen Beaver
		$i++;
1333
		}
1334 8f8682f7 Phil Davis
?>
1335 b5f6e690 Stephen Beaver
				</tbody>
1336 8f8682f7 Phil Davis
<?php
1337 b5f6e690 Stephen Beaver
	}
1338 8f8682f7 Phil Davis
?>
1339 82f54a42 Colin Fleming
		</table>
1340 b5f6e690 Stephen Beaver
	</div>
1341
</div>
1342 c9679d8c Stephen Beaver
1343 c10cb196 Stephen Beaver
<nav class="action-buttons">
1344 c9679d8c Stephen Beaver
	<a href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>" class="btn btn-sm btn-success">
1345 9d5a20cf heper
		<i class="fa fa-plus icon-embed-btn"></i>
1346 c9679d8c Stephen Beaver
		<?=gettext("Add")?>
1347
	</a>
1348
</nav>
1349 8f8682f7 Phil Davis
<?php
1350 b5f6e690 Stephen Beaver
}
1351 8f8682f7 Phil Davis
?>
1352
1353 8fd9052f Colin Fleming
<script type="text/javascript">
1354 b5f6e690 Stephen Beaver
//<![CDATA[
1355 6e3488e9 Phil Davis
events.push(function() {
1356 b5f6e690 Stephen Beaver
1357
	// Show advanced DNS options ======================================================================================
1358
	var showadvdns = false;
1359
1360
	function show_advdns() {
1361
<?php
1362
		if (!$pconfig['ddnsupdate'] && empty($pconfig['ddnsdomain']) && empty($pconfig['ddnsdomainprimary']) &&
1363 6e3488e9 Phil Davis
		    empty($pconfig['ddnsdomainkeyname']) && empty($pconfig['ddnsdomainkey'])) {
1364 b5f6e690 Stephen Beaver
			$hide = false;
1365 6e3488e9 Phil Davis
		} else {
1366 b5f6e690 Stephen Beaver
			$hide = true;
1367 6e3488e9 Phil Davis
		}
1368 8f8682f7 Phil Davis
?>
1369 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1370 b5f6e690 Stephen Beaver
1371
		hideCheckbox('ddnsupdate', !showadvdns && !hide);
1372
		hideInput('ddnsdomain', !showadvdns && !hide);
1373
		hideInput('ddnsdomainprimary', !showadvdns && !hide);
1374
		hideInput('ddnsdomainkeyname', !showadvdns && !hide);
1375
		hideInput('ddnsdomainkey', !showadvdns && !hide);
1376 8a73f407 Stephen Beaver
		hideInput('btnadvdns', hide);
1377 b5f6e690 Stephen Beaver
		showadvdns = !showadvdns;
1378
	}
1379
1380
	$('#btnadvdns').prop('type', 'button');
1381
1382
	$('#btnadvdns').click(function(event) {
1383
		show_advdns();
1384
	});
1385
1386
 // Show advanced MAC options ======================================================================================
1387
	var showadvmac = false;
1388
1389
	function show_advmac() {
1390 8f8682f7 Phil Davis
<?php
1391 6e3488e9 Phil Davis
		if (empty($pconfig['mac_allow']) && empty($pconfig['mac_deny'])) {
1392 b5f6e690 Stephen Beaver
			$hide = false;
1393 6e3488e9 Phil Davis
		} else {
1394 b5f6e690 Stephen Beaver
			$hide = true;
1395 6e3488e9 Phil Davis
		}
1396 8f8682f7 Phil Davis
?>
1397 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1398 b5f6e690 Stephen Beaver
1399
		hideInput('mac_allow', !showadvmac && !hide);
1400
		hideInput('mac_deny', !showadvmac && !hide);
1401
1402
		showadvmac = !showadvmac;
1403
	}
1404
1405
	$('#btnadvmac').prop('type', 'button');
1406
1407
	$('#btnadvmac').click(function(event) {
1408 ef2936e6 Stephen Beaver
		show_advmac(true);
1409 b5f6e690 Stephen Beaver
	});
1410
1411
  // Show advanced NTP options ======================================================================================
1412
	var showadvntp = false;
1413
1414
	function show_advntp() {
1415 8f8682f7 Phil Davis
<?php
1416 6e3488e9 Phil Davis
		if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1417 b5f6e690 Stephen Beaver
			$hide = false;
1418 6e3488e9 Phil Davis
		} else {
1419 b5f6e690 Stephen Beaver
			$hide = true;
1420 6e3488e9 Phil Davis
		}
1421 8f8682f7 Phil Davis
?>
1422 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1423 b5f6e690 Stephen Beaver
1424
		hideInput('ntp1', !showadvntp && !hide);
1425
		hideInput('ntp2', !showadvntp && !hide);
1426 8a73f407 Stephen Beaver
		hideInput('btnadvntp', hide);
1427 b5f6e690 Stephen Beaver
1428
		showadvntp = !showadvntp;
1429
	}
1430
1431
	$('#btnadvntp').prop('type', 'button');
1432
1433
	$('#btnadvntp').click(function(event) {
1434
		show_advntp();
1435
	});
1436
1437
   // Show advanced TFTP options ======================================================================================
1438 ef2936e6 Stephen Beaver
	var showtftp = false;
1439 b5f6e690 Stephen Beaver
1440
	function show_advtftp() {
1441 8f8682f7 Phil Davis
<?php
1442 6e3488e9 Phil Davis
		if (empty($pconfig['tftp'])) {
1443 b5f6e690 Stephen Beaver
			$hide = false;
1444 6e3488e9 Phil Davis
		} else {
1445 b5f6e690 Stephen Beaver
			$hide = true;
1446 6e3488e9 Phil Davis
		}
1447 8f8682f7 Phil Davis
?>
1448 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1449 b5f6e690 Stephen Beaver
1450 ef2936e6 Stephen Beaver
		hideInput('tftp', !showtftp & !hide);
1451 b5f6e690 Stephen Beaver
1452 ef2936e6 Stephen Beaver
		showtftp = !showtftp;
1453 b5f6e690 Stephen Beaver
	}
1454
1455
	$('#btnadvtftp').prop('type', 'button');
1456
1457
	$('#btnadvtftp').click(function(event) {
1458
		show_advtftp();
1459
	});
1460
1461
   // Show advanced LDAP options ======================================================================================
1462
	var showadvldap = false;
1463
1464
	function show_advldap() {
1465 8f8682f7 Phil Davis
<?php
1466 6e3488e9 Phil Davis
		if (empty($pconfig['ldap'])) {
1467 b5f6e690 Stephen Beaver
			$hide = false;
1468 6e3488e9 Phil Davis
		} else {
1469 b5f6e690 Stephen Beaver
			$hide = true;
1470 6e3488e9 Phil Davis
		}
1471 8f8682f7 Phil Davis
?>
1472 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1473 b5f6e690 Stephen Beaver
1474
		hideInput('ldap', !showadvldap && !hide);
1475 8a73f407 Stephen Beaver
		hideInput('btnadvldap', hide);
1476 b5f6e690 Stephen Beaver
1477
		showadvldap = !showadvldap;
1478
	}
1479
1480
	$('#btnadvldap').prop('type', 'button');
1481
1482
	$('#btnadvldap').click(function(event) {
1483
		show_advldap();
1484
	});
1485
1486 eef93144 Jared Dillard
	// Show advanced additional opts options ===========================================================================
1487 b5f6e690 Stephen Beaver
	var showadvopts = false;
1488
1489
	function show_advopts() {
1490 8f8682f7 Phil Davis
<?php
1491 6e3488e9 Phil Davis
		if (empty($pconfig['numberoptions']) ||
1492
		    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1493 b5f6e690 Stephen Beaver
			$hide = false;
1494 6e3488e9 Phil Davis
		} else {
1495 b5f6e690 Stephen Beaver
			$hide = true;
1496 6e3488e9 Phil Davis
		}
1497 8f8682f7 Phil Davis
?>
1498 6e3488e9 Phil Davis
		var hide = <?php if ($hide) {echo 'true';} else {echo 'false';} ?>;
1499 b5f6e690 Stephen Beaver
1500
		hideClass('adnlopts', !showadvopts && !hide);
1501 8a73f407 Stephen Beaver
		hideInput('btnadvopts', hide);
1502 b5f6e690 Stephen Beaver
1503
		showadvopts = !showadvopts;
1504
	}
1505
1506
	$('#btnadvopts').prop('type', 'button');
1507
1508
	$('#btnadvopts').click(function(event) {
1509
		show_advopts();
1510
	});
1511
1512 eef93144 Jared Dillard
	// ---------- On initial page load ------------------------------------------------------------
1513
1514 b5f6e690 Stephen Beaver
	show_advdns();
1515
	show_advmac();
1516
	show_advntp();
1517
	show_advtftp();
1518
	show_advldap();
1519
	show_advopts();
1520 0bc61baa Stephen Beaver
1521
	// Suppress "Delete row" button if there are fewer than two rows
1522
	checkLastRow();
1523 b5f6e690 Stephen Beaver
});
1524 180db186 Colin Fleming
//]]>
1525 5b237745 Scott Ullrich
</script>
1526 b5f6e690 Stephen Beaver
1527 3c9befb9 Chris Buechler
<?php include("foot.inc");