Project

General

Profile

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