Project

General

Profile

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