Project

General

Profile

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