Project

General

Profile

Download (56.7 KB) Statistics
| Branch: | Tag: | Revision:
1 e9f147c8 Scott Ullrich
<?php
2 5b237745 Scott Ullrich
/*
3 c5d81585 Renato Botelho
 * services_dhcp.php
4 919d91f9 Phil Davis
 *
5 c5d81585 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 b8f91b7c Luiz Souza
 * Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
7 c5d81585 Renato Botelho
 * All rights reserved.
8 b5f6e690 Stephen Beaver
 *
9 c5d81585 Renato Botelho
 * originally based on m0n0wall (http://m0n0.ch/wall)
10
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
 * All rights reserved.
12 b5f6e690 Stephen Beaver
 *
13 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
14
 * you may not use this file except in compliance with the License.
15
 * You may obtain a copy of the License at
16 b5f6e690 Stephen Beaver
 *
17 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
18 b5f6e690 Stephen Beaver
 *
19 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
20
 * distributed under the License is distributed on an "AS IS" BASIS,
21
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
 * See the License for the specific language governing permissions and
23
 * limitations under the License.
24 b5f6e690 Stephen Beaver
 */
25 5b237745 Scott Ullrich
26 6b07c15a Matthew Grooms
##|+PRIV
27
##|*IDENT=page-services-dhcpserver
28 9599211d jim-p
##|*NAME=Services: DHCP Server
29
##|*DESCR=Allow access to the 'Services: DHCP Server' page.
30 6b07c15a Matthew Grooms
##|*MATCH=services_dhcp.php*
31
##|-PRIV
32
33 c81ef6e2 Phil Davis
require_once("guiconfig.inc");
34 6c124212 Phil Davis
require_once("filter.inc");
35 6303601e heper
require_once('rrd.inc');
36
require_once("shaper.inc");
37 5b237745 Scott Ullrich
38 8f8682f7 Phil Davis
if (!$g['services_dhcp_server_enable']) {
39 6f3d2063 Renato Botelho
	header("Location: /");
40 2ee0410f Scott Ullrich
	exit;
41
}
42
43 c946d721 Steve Beaver
$if = $_REQUEST['if'];
44 e9f147c8 Scott Ullrich
45 11bc553c Scott Ullrich
/* if OLSRD is enabled, allow WAN to house DHCP. */
46 8f8682f7 Phil Davis
if ($config['installedpackages']['olsrd']) {
47
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
48
		if ($olsrd['enable']) {
49
			$is_olsr_enabled = true;
50
			break;
51
		}
52 a3b466b5 Scott Ullrich
	}
53 8f8682f7 Phil Davis
}
54 5b237745 Scott Ullrich
55 934240ef Ermal Luçi
$iflist = get_configured_interface_with_descr();
56 5b237745 Scott Ullrich
57 1c451b06 Scott Ullrich
/* set the starting interface */
58 f19651d1 Ermal
if (!$if || !isset($iflist[$if])) {
59 cde97f1c Phil Davis
	$found_starting_if = false;
60
	// First look for an interface with DHCP already enabled.
61 01fdb2d3 Erik Fonnesbeck
	foreach ($iflist as $ifent => $ifname) {
62 de792e62 jim-p
		$oc = $config['interfaces'][$ifent];
63 403dad2a Renato Botelho
		if (is_array($config['dhcpd'][$ifent]) &&
64
		    isset($config['dhcpd'][$ifent]['enable']) &&
65
		    is_ipaddrv4($oc['ipaddr']) && $oc['subnet'] < 31) {
66 cde97f1c Phil Davis
			$if = $ifent;
67
			$found_starting_if = true;
68
			break;
69 8f8682f7 Phil Davis
		}
70 cde97f1c Phil Davis
	}
71
72 403dad2a Renato Botelho
	/*
73
	 * If there is no DHCP-enabled interface and LAN is a candidate,
74
	 * then choose LAN.
75
	 */
76
	if (!$found_starting_if && isset($iflist['lan']) &&
77
	    is_ipaddrv4($config['interfaces']['lan']['ipaddr']) &&
78
	    $config['interfaces']['lan']['subnet'] < 31) {
79 cde97f1c Phil Davis
		$if = 'lan';
80
		$found_starting_if = true;
81
	}
82 b5f6e690 Stephen Beaver
83 cde97f1c Phil Davis
	// At the last select whatever can be found.
84
	if (!$found_starting_if) {
85
		foreach ($iflist as $ifent => $ifname) {
86
			$oc = $config['interfaces'][$ifent];
87 403dad2a Renato Botelho
88
			/* Not static IPv4 or subnet >= 31 */
89
			if (!is_ipaddrv4($oc['ipaddr']) ||
90
			    empty($oc['subnet']) || $oc['subnet'] < 31) {
91
				continue;
92
			}
93
94
			if (!is_array($config['dhcpd'][$ifent]) ||
95
			    !isset($config['dhcpd'][$ifent]['enable'])) {
96 cde97f1c Phil Davis
				continue;
97
			}
98
99
			$if = $ifent;
100
			break;
101
		}
102 01fdb2d3 Erik Fonnesbeck
	}
103 f19651d1 Ermal
}
104 0a2c6a5b Scott Ullrich
105 c946d721 Steve Beaver
$act = $_REQUEST['act'];
106 cba980f6 jim-p
107 cc6052f0 Renato Botelho
$a_pools = array();
108 cba980f6 jim-p
109 8f8682f7 Phil Davis
if (is_array($config['dhcpd'][$if])) {
110 c946d721 Steve Beaver
	$pool = $_REQUEST['pool'];
111 8f8682f7 Phil Davis
	if (is_numeric($_POST['pool'])) {
112 cba980f6 jim-p
		$pool = $_POST['pool'];
113 8f8682f7 Phil Davis
	}
114 cba980f6 jim-p
115
	// If we have a pool but no interface name, that's not valid. Redirect away.
116
	if (is_numeric($pool) && empty($if)) {
117
		header("Location: services_dhcp.php");
118
		exit;
119 de792e62 jim-p
	}
120 cba980f6 jim-p
121 8f8682f7 Phil Davis
	if (!is_array($config['dhcpd'][$if]['pool'])) {
122 cba980f6 jim-p
		$config['dhcpd'][$if]['pool'] = array();
123 8f8682f7 Phil Davis
	}
124 b5f6e690 Stephen Beaver
125 cba980f6 jim-p
	$a_pools = &$config['dhcpd'][$if]['pool'];
126
127 8f8682f7 Phil Davis
	if (is_numeric($pool) && $a_pools[$pool]) {
128 cba980f6 jim-p
		$dhcpdconf = &$a_pools[$pool];
129 8f8682f7 Phil Davis
	} elseif ($act == "newpool") {
130 cba980f6 jim-p
		$dhcpdconf = array();
131 8f8682f7 Phil Davis
	} else {
132 cba980f6 jim-p
		$dhcpdconf = &$config['dhcpd'][$if];
133 8f8682f7 Phil Davis
	}
134 e7940d2e Phil Davis
135
	if (!is_array($config['dhcpd'][$if]['staticmap'])) {
136
		$dhcpdconf['staticmap'] = array();
137
	}
138
139
	$a_maps = &$config['dhcpd'][$if]['staticmap'];
140 cba980f6 jim-p
}
141 c946d721 Steve Beaver
142 cba980f6 jim-p
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 ee1fb205 jim-p
	} else {
162
		// Options that exist only in pools
163
		$pconfig['descr'] = $dhcpdconf['descr'];
164 cba980f6 jim-p
	}
165
166
	// Options that can be global or per-pool.
167
	if (is_array($dhcpdconf['range'])) {
168
		$pconfig['range_from'] = $dhcpdconf['range']['from'];
169
		$pconfig['range_to'] = $dhcpdconf['range']['to'];
170
	}
171 b5f6e690 Stephen Beaver
172 cba980f6 jim-p
	$pconfig['deftime'] = $dhcpdconf['defaultleasetime'];
173
	$pconfig['maxtime'] = $dhcpdconf['maxleasetime'];
174
	$pconfig['gateway'] = $dhcpdconf['gateway'];
175
	$pconfig['domain'] = $dhcpdconf['domain'];
176
	$pconfig['domainsearchlist'] = $dhcpdconf['domainsearchlist'];
177 8f8682f7 Phil Davis
	list($pconfig['wins1'], $pconfig['wins2']) = $dhcpdconf['winsserver'];
178
	list($pconfig['dns1'], $pconfig['dns2'], $pconfig['dns3'], $pconfig['dns4']) = $dhcpdconf['dnsserver'];
179 6d53301b Jose Luis Duran
	$pconfig['ignorebootp'] = isset($dhcpdconf['ignorebootp']);
180 cba980f6 jim-p
	$pconfig['denyunknown'] = isset($dhcpdconf['denyunknown']);
181 11ee0c6d Brett Keller
	$pconfig['ignoreclientuids'] = isset($dhcpdconf['ignoreclientuids']);
182 3475eb04 Andrew Pilloud
	$pconfig['nonak'] = isset($dhcpdconf['nonak']);
183 cba980f6 jim-p
	$pconfig['ddnsdomain'] = $dhcpdconf['ddnsdomain'];
184 87019fc4 Andres Petralli
	$pconfig['ddnsdomainprimary'] = $dhcpdconf['ddnsdomainprimary'];
185
	$pconfig['ddnsdomainkeyname'] = $dhcpdconf['ddnsdomainkeyname'];
186 534d7d69 Joeri Capens
	$pconfig['ddnsdomainkeyalgorithm'] = $dhcpdconf['ddnsdomainkeyalgorithm'];
187 87019fc4 Andres Petralli
	$pconfig['ddnsdomainkey'] = $dhcpdconf['ddnsdomainkey'];
188 cba980f6 jim-p
	$pconfig['ddnsupdate'] = isset($dhcpdconf['ddnsupdate']);
189 cf15bcb4 Ross Williams
	$pconfig['ddnsforcehostname'] = isset($dhcpdconf['ddnsforcehostname']);
190 cba980f6 jim-p
	$pconfig['mac_allow'] = $dhcpdconf['mac_allow'];
191
	$pconfig['mac_deny'] = $dhcpdconf['mac_deny'];
192 8f8682f7 Phil Davis
	list($pconfig['ntp1'], $pconfig['ntp2']) = $dhcpdconf['ntpserver'];
193 cba980f6 jim-p
	$pconfig['tftp'] = $dhcpdconf['tftp'];
194
	$pconfig['ldap'] = $dhcpdconf['ldap'];
195
	$pconfig['netboot'] = isset($dhcpdconf['netboot']);
196
	$pconfig['nextserver'] = $dhcpdconf['nextserver'];
197
	$pconfig['filename'] = $dhcpdconf['filename'];
198 7023c602 Charlie Root
	$pconfig['filename32'] = $dhcpdconf['filename32'];
199
	$pconfig['filename64'] = $dhcpdconf['filename64'];
200 cba980f6 jim-p
	$pconfig['rootpath'] = $dhcpdconf['rootpath'];
201
	$pconfig['netmask'] = $dhcpdconf['netmask'];
202
	$pconfig['numberoptions'] = $dhcpdconf['numberoptions'];
203 18d316a5 heper
	$pconfig['statsgraph'] = $dhcpdconf['statsgraph'];
204 67784aa6 Steve Beaver
	$pconfig['ddnsclientupdates'] = $dhcpdconf['ddnsclientupdates'];
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 b90d635e Renato Botelho
$subnet_start = gen_subnetv4($ifcfgip, $ifcfgsn);
211
$subnet_end = gen_subnetv4_max($ifcfgip, $ifcfgsn);
212
213 1f1a08c8 jim-p
function validate_partial_mac_list($maclist) {
214
	$macs = explode(',', $maclist);
215
216
	// Loop through and look for invalid MACs.
217 8f8682f7 Phil Davis
	foreach ($macs as $mac) {
218
		if (!is_macaddr($mac, true)) {
219 1f1a08c8 jim-p
			return false;
220 8f8682f7 Phil Davis
		}
221
	}
222 b5f6e690 Stephen Beaver
223 1f1a08c8 jim-p
	return true;
224
}
225
226 141d8913 jim-p
if (isset($_POST['save'])) {
227 5b237745 Scott Ullrich
228
	unset($input_errors);
229 b7597d4e Bill Marquette
230 5b237745 Scott Ullrich
	$pconfig = $_POST;
231
232 6d1af0e9 jim-p
	$numberoptions = array();
233 6c07db48 Phil Davis
	for ($x = 0; $x < 99; $x++) {
234 8f8682f7 Phil Davis
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
235 60682dd2 Michael Newton
			if ($_POST["number{$x}"] < 1 || $_POST["number{$x}"] > 254) {
236
				$input_errors[] = gettext("The DHCP option must be a number between 1 and 254.");
237
				continue;
238
			}
239 6d1af0e9 jim-p
			$numbervalue = array();
240
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
241 678dfd0f Erik Fonnesbeck
			$numbervalue['type'] = htmlspecialchars($_POST["itemtype{$x}"]);
242 65cce9d7 Renato Botelho
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
243 6d1af0e9 jim-p
			$numberoptions['item'][] = $numbervalue;
244
		}
245
	}
246 b5f6e690 Stephen Beaver
247 466aae83 Phil Davis
	// Reload the new pconfig variable that the form uses.
248 6d1af0e9 jim-p
	$pconfig['numberoptions'] = $numberoptions;
249
250 5b237745 Scott Ullrich
	/* input validation */
251 48614394 Phil Davis
252
	// Note: if DHCP Server is not enabled, then it is OK to adjust other parameters without specifying range from-to.
253 cba980f6 jim-p
	if ($_POST['enable'] || is_numeric($pool) || $act == "newpool") {
254 5b237745 Scott Ullrich
		$reqdfields = explode(" ", "range_from range_to");
255 8f8682f7 Phil Davis
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
256 e9f147c8 Scott Ullrich
257 507628d5 Renato Botelho
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
258 48614394 Phil Davis
	}
259 de792e62 jim-p
260 48614394 Phil Davis
	if (($_POST['nonak']) && !empty($_POST['failover_peerip'])) {
261
		$input_errors[] = gettext("Ignore Denied Clients may not be used when a Failover Peer IP is defined.");
262
	}
263 8209517d jim-p
264 48614394 Phil Davis
	if ($_POST['range_from'] && !is_ipaddrv4($_POST['range_from'])) {
265
		$input_errors[] = gettext("A valid IPv4 address must be specified for range from.");
266
	}
267
	if ($_POST['range_to'] && !is_ipaddrv4($_POST['range_to'])) {
268
		$input_errors[] = gettext("A valid IPv4 address must be specified for range to.");
269
	}
270
	if (($_POST['range_from'] && !$_POST['range_to']) || ($_POST['range_to'] && !$_POST['range_from'])) {
271
		$input_errors[] = gettext("Range From and Range To must both be entered.");
272
	}
273
	if (($_POST['gateway'] && $_POST['gateway'] != "none" && !is_ipaddrv4($_POST['gateway']))) {
274
		$input_errors[] = gettext("A valid IP address must be specified for the gateway.");
275
	}
276
	if (($_POST['wins1'] && !is_ipaddrv4($_POST['wins1'])) || ($_POST['wins2'] && !is_ipaddrv4($_POST['wins2']))) {
277
		$input_errors[] = gettext("A valid IP address must be specified for the primary/secondary WINS servers.");
278
	}
279
	$parent_ip = get_interface_ip($_POST['if']);
280
	if (is_ipaddrv4($parent_ip) && $_POST['gateway'] && $_POST['gateway'] != "none") {
281
		$parent_sn = get_interface_subnet($_POST['if']);
282
		if (!ip_in_subnet($_POST['gateway'], gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn) && !ip_in_interface_alias_subnet($_POST['if'], $_POST['gateway'])) {
283
			$input_errors[] = sprintf(gettext("The gateway address %s does not lie within the chosen interface's subnet."), $_POST['gateway']);
284 45d1024d Scott Ullrich
		}
285 48614394 Phil Davis
	}
286 b5f6e690 Stephen Beaver
287 48614394 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']))) {
288
		$input_errors[] = gettext("A valid IP address must be specified for each of the DNS servers.");
289
	}
290
291
	if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
292
		$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
293
	}
294 26e3ca70 sullrich
295 48614394 Phil Davis
	if (isset($config['captiveportal']) && is_array($config['captiveportal'])) {
296
		$deftime = 7200; // Default value if it's empty
297
		if (is_numeric($_POST['deftime'])) {
298
			$deftime = $_POST['deftime'];
299 8f8682f7 Phil Davis
		}
300 e680b2f9 Renato Botelho
301 48614394 Phil Davis
		foreach ($config['captiveportal'] as $cpZone => $cpdata) {
302
			if (!isset($cpdata['enable'])) {
303
				continue;
304 8f8682f7 Phil Davis
			}
305 48614394 Phil Davis
			if (!isset($cpdata['timeout']) || !is_numeric($cpdata['timeout'])) {
306
				continue;
307
			}
308
			$cp_ifs = explode(',', $cpdata['interface']);
309
			if (!in_array($if, $cp_ifs)) {
310
				continue;
311
			}
312
			if ($cpdata['timeout'] > $deftime) {
313
				$input_errors[] = sprintf(gettext(
314
					'The Captive Portal zone (%1$s) has Hard Timeout parameter set to a value bigger than Default lease time (%2$s).'), $cpZone, $deftime);
315 e680b2f9 Renato Botelho
			}
316
		}
317 48614394 Phil Davis
	}
318 e680b2f9 Renato Botelho
319 48614394 Phil Davis
	if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
320
		$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
321
	}
322 534d7d69 Joeri Capens
	if ($_POST['ddnsupdate'] && !is_domain($_POST['ddnsdomain'])) {
323 48614394 Phil Davis
		$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
324
	}
325 534d7d69 Joeri Capens
	if ($_POST['ddnsupdate'] && !is_ipaddrv4($_POST['ddnsdomainprimary'])) {
326 48614394 Phil Davis
		$input_errors[] = gettext("A valid primary domain name server IP address must be specified for the dynamic domain name.");
327
	}
328 534d7d69 Joeri Capens
	if ($_POST['ddnsupdate'] && (!$_POST['ddnsdomainkeyname'] || !$_POST['ddnsdomainkeyalgorithm'] || !$_POST['ddnsdomainkey'])) {
329
		$input_errors[] = gettext("A valid domain key name, algorithm and secret must be specified.");
330 48614394 Phil Davis
	}
331
	if ($_POST['domainsearchlist']) {
332
		$domain_array = preg_split("/[ ;]+/", $_POST['domainsearchlist']);
333
		foreach ($domain_array as $curdomain) {
334
			if (!is_domain($curdomain)) {
335
				$input_errors[] = gettext("A valid domain search list must be specified.");
336
				break;
337 42a3cbab Pierre POMES
			}
338
		}
339 48614394 Phil Davis
	}
340 1f1a08c8 jim-p
341 48614394 Phil Davis
	// Validate MACs
342
	if (!empty($_POST['mac_allow']) && !validate_partial_mac_list($_POST['mac_allow'])) {
343
		$input_errors[] = gettext("If a mac allow list is specified, it must contain only valid partial MAC addresses.");
344
	}
345
	if (!empty($_POST['mac_deny']) && !validate_partial_mac_list($_POST['mac_deny'])) {
346
		$input_errors[] = gettext("If a mac deny list is specified, it must contain only valid partial MAC addresses.");
347
	}
348 1f1a08c8 jim-p
349 48614394 Phil Davis
	if (($_POST['ntp1'] && (!is_ipaddrv4($_POST['ntp1']) && !is_hostname($_POST['ntp1']))) || ($_POST['ntp2'] && (!is_ipaddrv4($_POST['ntp2']) && !is_hostname($_POST['ntp2'])))) {
350
		$input_errors[] = gettext("A valid IP address or hostname must be specified for the primary/secondary NTP servers.");
351
	}
352
	if (($_POST['domain'] && !is_domain($_POST['domain']))) {
353
		$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
354
	}
355
	if ($_POST['tftp'] && !is_ipaddrv4($_POST['tftp']) && !is_domain($_POST['tftp']) && !filter_var($_POST['tftp'], FILTER_VALIDATE_URL)) {
356
		$input_errors[] = gettext("A valid IP address, hostname or URL must be specified for the TFTP server.");
357
	}
358
	if (($_POST['nextserver'] && !is_ipaddrv4($_POST['nextserver']))) {
359
		$input_errors[] = gettext("A valid IP address must be specified for the network boot server.");
360
	}
361 2c75b451 sullrich
362 48614394 Phil Davis
	if (gen_subnet($ifcfgip, $ifcfgsn) == $_POST['range_from']) {
363
		$input_errors[] = gettext("The network address cannot be used in the starting subnet range.");
364
	}
365
	if (gen_subnet_max($ifcfgip, $ifcfgsn) == $_POST['range_to']) {
366
		$input_errors[] = gettext("The broadcast address cannot be used in the ending subnet range.");
367
	}
368 e9f147c8 Scott Ullrich
369 48614394 Phil Davis
	// Disallow a range that includes the virtualip
370
	if (is_array($config['virtualip']['vip'])) {
371
		foreach ($config['virtualip']['vip'] as $vip) {
372
			if ($vip['interface'] == $if) {
373
				if ($vip['subnet'] && is_inrange_v4($vip['subnet'], $_POST['range_from'], $_POST['range_to'])) {
374
					$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IP address %s."), $vip['subnet']);
375 8f8682f7 Phil Davis
				}
376 7dfa60fa Ermal Lu?i
			}
377 2c75b451 sullrich
		}
378 48614394 Phil Davis
	}
379 2c75b451 sullrich
380 48614394 Phil Davis
	$noip = false;
381
	if (is_array($a_maps)) {
382
		foreach ($a_maps as $map) {
383
			if (empty($map['ipaddr'])) {
384
				$noip = true;
385 8f8682f7 Phil Davis
			}
386
		}
387 48614394 Phil Davis
	}
388 b5f6e690 Stephen Beaver
389 48614394 Phil Davis
	if ($_POST['staticarp'] && $noip) {
390
		$input_errors[] = gettext("Cannot enable static ARP when there are static map entries without IP addresses. Ensure all static maps have IP addresses and try again.");
391
	}
392
393
	if (is_array($pconfig['numberoptions']['item'])) {
394
		foreach ($pconfig['numberoptions']['item'] as $numberoption) {
395
			$numberoption_value = base64_decode($numberoption['value']);
396
			if ($numberoption['type'] == 'text' && strstr($numberoption_value, '"')) {
397
				$input_errors[] = gettext("Text type cannot include quotation marks.");
398
			} else if ($numberoption['type'] == 'string' && !preg_match('/^"[^"]*"$/', $numberoption_value) && !preg_match('/^[0-9a-f]{2}(?:\:[0-9a-f]{2})*$/i', $numberoption_value)) {
399
				$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");
400
			} else if ($numberoption['type'] == 'boolean' && $numberoption_value != 'true' && $numberoption_value != 'false' && $numberoption_value != 'on' && $numberoption_value != 'off') {
401
				$input_errors[] = gettext("Boolean type must be true, false, on, or off.");
402
			} else if ($numberoption['type'] == 'unsigned integer 8' && (!is_numeric($numberoption_value) || $numberoption_value < 0 || $numberoption_value > 255)) {
403
				$input_errors[] = gettext("Unsigned 8-bit integer type must be a number in the range 0 to 255.");
404
			} else if ($numberoption['type'] == 'unsigned integer 16' && (!is_numeric($numberoption_value) || $numberoption_value < 0 || $numberoption_value > 65535)) {
405
				$input_errors[] = gettext("Unsigned 16-bit integer type must be a number in the range 0 to 65535.");
406
			} else if ($numberoption['type'] == 'unsigned integer 32' && (!is_numeric($numberoption_value) || $numberoption_value < 0 || $numberoption_value > 4294967295)) {
407
				$input_errors[] = gettext("Unsigned 32-bit integer type must be a number in the range 0 to 4294967295.");
408
			} else if ($numberoption['type'] == 'signed integer 8' && (!is_numeric($numberoption_value) || $numberoption_value < -128 || $numberoption_value > 127)) {
409
				$input_errors[] = gettext("Signed 8-bit integer type must be a number in the range -128 to 127.");
410
			} else if ($numberoption['type'] == 'signed integer 16' && (!is_numeric($numberoption_value) || $numberoption_value < -32768 || $numberoption_value > 32767)) {
411
				$input_errors[] = gettext("Signed 16-bit integer type must be a number in the range -32768 to 32767.");
412
			} else if ($numberoption['type'] == 'signed integer 32' && (!is_numeric($numberoption_value) || $numberoption_value < -2147483648 || $numberoption_value > 2147483647)) {
413
				$input_errors[] = gettext("Signed 32-bit integer type must be a number in the range -2147483648 to 2147483647.");
414
			} else if ($numberoption['type'] == 'ip-address' && !is_ipaddrv4($numberoption_value) && !is_hostname($numberoption_value)) {
415
				$input_errors[] = gettext("IP address or host type must be an IP address or host name.");
416 678dfd0f Erik Fonnesbeck
			}
417
		}
418 48614394 Phil Davis
	}
419 678dfd0f Erik Fonnesbeck
420 4b980701 Renato Botelho
	if ((!isset($pool) || !is_numeric($pool)) && $act != "newpool") {
421
		/* If enabling DHCP Server, make sure that the DHCP Relay isn't enabled on this interface */
422
		if ($_POST['enable'] && isset($config['dhcrelay']['enable']) &&
423
		    (stristr($config['dhcrelay']['interface'], $if) !== false)) {
424
			$input_errors[] = sprintf(gettext(
425
			    "The DHCP relay on the %s interface must be disabled before enabling the DHCP server."),
426
			    $iflist[$if]);
427 e83c9b73 doktornotor
		}
428 4b980701 Renato Botelho
429
		/* If disabling DHCP Server, make sure that DHCP registration isn't enabled for DNS forwarder/resolver */
430
		if (!$_POST['enable']) {
431 9477c170 jim-p
			/* Find out how many other interfaces have DHCP enabled. */
432
			$dhcp_enabled_count = 0;
433
			foreach ($config['dhcpd'] as $dhif => $dhcps) {
434
				if ($dhif == $if) {
435
					/* Skip this interface, we only want to know how many others are enabled. */
436
					continue;
437
				}
438
				if (isset($dhcps['enable'])) {
439
					$dhcp_enabled_count++;
440
				}
441
			}
442
443 4b980701 Renato Botelho
			if (isset($config['dnsmasq']['enable']) &&
444 9477c170 jim-p
			    ($dhcp_enabled_count == 0) &&
445 4b980701 Renato Botelho
			    (isset($config['dnsmasq']['regdhcp']) ||
446
			    isset($config['dnsmasq']['regdhcpstatic']) ||
447
			    isset($config['dnsmasq']['dhcpfirst']))) {
448
				$input_errors[] = gettext(
449 9477c170 jim-p
				    "DHCP Registration features in the DNS Forwarder are active and require at least one enabled DHCP Server.");
450 4b980701 Renato Botelho
			}
451
			if (isset($config['unbound']['enable']) &&
452 9477c170 jim-p
			    ($dhcp_enabled_count == 0) &&
453 4b980701 Renato Botelho
			    (isset($config['unbound']['regdhcp']) ||
454
			    isset($config['unbound']['regdhcpstatic']))) {
455
				$input_errors[] = gettext(
456 9477c170 jim-p
				    "DHCP Registration features in the DNS Resolver are active and require at least one enabled DHCP Server.");
457 4b980701 Renato Botelho
			}
458 e83c9b73 doktornotor
		}
459
	}
460
461 48614394 Phil Davis
	// If nothing is wrong so far, and we have range from and to, then check conditions related to the values of range from and to.
462
	if (!$input_errors && $_POST['range_from'] && $_POST['range_to']) {
463
		/* make sure the range lies within the current subnet */
464
		if (ip_greater_than($_POST['range_from'], $_POST['range_to'])) {
465
			$input_errors[] = gettext("The range is invalid (first element higher than second element).");
466
		}
467
468
		if (!is_inrange_v4($_POST['range_from'], $subnet_start, $subnet_end) ||
469
			!is_inrange_v4($_POST['range_to'], $subnet_start, $subnet_end)) {
470
			$input_errors[] = gettext("The specified range lies outside of the current subnet.");
471
		}
472
473
		if (is_numeric($pool) || ($act == "newpool")) {
474
			if (is_inrange_v4($_POST['range_from'],
475
				$config['dhcpd'][$if]['range']['from'],
476
				$config['dhcpd'][$if]['range']['to']) ||
477
				is_inrange_v4($_POST['range_to'],
478
				$config['dhcpd'][$if]['range']['from'],
479
				$config['dhcpd'][$if]['range']['to'])) {
480
				$input_errors[] = gettext("The specified range must not be within the DHCP range for this interface.");
481 8f8682f7 Phil Davis
			}
482 48614394 Phil Davis
		}
483 e9f147c8 Scott Ullrich
484 48614394 Phil Davis
		foreach ($a_pools as $id => $p) {
485
			if (is_numeric($pool) && ($id == $pool)) {
486
				continue;
487 ec513fa9 stilez
			}
488
489 48614394 Phil Davis
			if (is_inrange_v4($_POST['range_from'],
490
				$p['range']['from'], $p['range']['to']) ||
491
				is_inrange_v4($_POST['range_to'],
492
				$p['range']['from'], $p['range']['to'])) {
493
				$input_errors[] = gettext("The specified range must not be within the range configured on a DHCP pool for this interface.");
494
				break;
495 f657f5e1 Renato Botelho
			}
496 48614394 Phil Davis
		}
497 f657f5e1 Renato Botelho
498 48614394 Phil Davis
		if (is_array($a_maps)) {
499
			foreach ($a_maps as $map) {
500
				if (empty($map['ipaddr'])) {
501 f657f5e1 Renato Botelho
					continue;
502 8f8682f7 Phil Davis
				}
503 48614394 Phil Davis
				if (is_inrange_v4($map['ipaddr'], $_POST['range_from'], $_POST['range_to'])) {
504
					$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
505 f657f5e1 Renato Botelho
					break;
506
				}
507
			}
508 5b237745 Scott Ullrich
		}
509
	}
510
511
	if (!$input_errors) {
512 cba980f6 jim-p
		if (!is_numeric($pool)) {
513
			if ($act == "newpool") {
514
				$dhcpdconf = array();
515
			} else {
516 8a228b83 Stephen Jones
				if (!is_array($config['dhcpd'])) {
517
					$config['dhcpd']= array();
518
				}
519 8f8682f7 Phil Davis
				if (!is_array($config['dhcpd'][$if])) {
520 cba980f6 jim-p
					$config['dhcpd'][$if] = array();
521 8f8682f7 Phil Davis
				}
522 cba980f6 jim-p
				$dhcpdconf = $config['dhcpd'][$if];
523
			}
524
		} else {
525
			if (is_array($a_pools[$pool])) {
526
				$dhcpdconf = $a_pools[$pool];
527
			} else {
528
				// Someone specified a pool but it doesn't exist. Punt.
529
				header("Location: services_dhcp.php");
530
				exit;
531
			}
532
		}
533 8a228b83 Stephen Jones
		if (!is_array($dhcpdconf)) {
534
			$dhcpdconf = array();
535
		}
536 8f8682f7 Phil Davis
		if (!is_array($dhcpdconf['range'])) {
537 cba980f6 jim-p
			$dhcpdconf['range'] = array();
538 8f8682f7 Phil Davis
		}
539 cba980f6 jim-p
540 6c124212 Phil Davis
		$dhcpd_enable_changed = false;
541
542 cba980f6 jim-p
		// Global Options
543
		if (!is_numeric($pool) && !($act == "newpool")) {
544 6c124212 Phil Davis
			$old_dhcpd_enable = isset($dhcpdconf['enable']);
545
			$new_dhcpd_enable = ($_POST['enable']) ? true : false;
546
			if ($old_dhcpd_enable != $new_dhcpd_enable) {
547
				/* DHCP has been enabled or disabled. The pf ruleset will need to be rebuilt to allow or disallow DHCP. */
548
				$dhcpd_enable_changed = true;
549
			}
550 b5f6e690 Stephen Beaver
551 6c124212 Phil Davis
			$dhcpdconf['enable'] = $new_dhcpd_enable;
552 cba980f6 jim-p
			$dhcpdconf['staticarp'] = ($_POST['staticarp']) ? true : false;
553
			$previous = $dhcpdconf['failover_peerip'];
554 b5f6e690 Stephen Beaver
			if ($previous != $_POST['failover_peerip']) {
555 cba980f6 jim-p
				mwexec("/bin/rm -rf /var/dhcpd/var/db/*");
556 8f8682f7 Phil Davis
			}
557 b5f6e690 Stephen Beaver
558 cba980f6 jim-p
			$dhcpdconf['failover_peerip'] = $_POST['failover_peerip'];
559 466aae83 Phil Davis
			// dhcpleaseinlocaltime is global to all interfaces. So update the setting on all interfaces.
560
			foreach ($config['dhcpd'] as &$dhcpdifitem) {
561
				$dhcpdifitem['dhcpleaseinlocaltime'] = $_POST['dhcpleaseinlocaltime'];
562
			}
563 ee1fb205 jim-p
		} else {
564
			// Options that exist only in pools
565
			$dhcpdconf['descr'] = $_POST['descr'];
566 cba980f6 jim-p
		}
567
568
		// Options that can be global or per-pool.
569
		$dhcpdconf['range']['from'] = $_POST['range_from'];
570
		$dhcpdconf['range']['to'] = $_POST['range_to'];
571
		$dhcpdconf['defaultleasetime'] = $_POST['deftime'];
572
		$dhcpdconf['maxleasetime'] = $_POST['maxtime'];
573
		$dhcpdconf['netmask'] = $_POST['netmask'];
574
575
		unset($dhcpdconf['winsserver']);
576 8f8682f7 Phil Davis
		if ($_POST['wins1']) {
577 cba980f6 jim-p
			$dhcpdconf['winsserver'][] = $_POST['wins1'];
578 8f8682f7 Phil Davis
		}
579
		if ($_POST['wins2']) {
580 cba980f6 jim-p
			$dhcpdconf['winsserver'][] = $_POST['wins2'];
581 8f8682f7 Phil Davis
		}
582 4cab31d0 Scott Ullrich
583 cba980f6 jim-p
		unset($dhcpdconf['dnsserver']);
584 8f8682f7 Phil Davis
		if ($_POST['dns1']) {
585 cba980f6 jim-p
			$dhcpdconf['dnsserver'][] = $_POST['dns1'];
586 8f8682f7 Phil Davis
		}
587
		if ($_POST['dns2']) {
588 cba980f6 jim-p
			$dhcpdconf['dnsserver'][] = $_POST['dns2'];
589 8f8682f7 Phil Davis
		}
590
		if ($_POST['dns3']) {
591 3b5707db Phil Davis
			$dhcpdconf['dnsserver'][] = $_POST['dns3'];
592 8f8682f7 Phil Davis
		}
593
		if ($_POST['dns4']) {
594 3b5707db Phil Davis
			$dhcpdconf['dnsserver'][] = $_POST['dns4'];
595 8f8682f7 Phil Davis
		}
596 cba980f6 jim-p
597
		$dhcpdconf['gateway'] = $_POST['gateway'];
598
		$dhcpdconf['domain'] = $_POST['domain'];
599
		$dhcpdconf['domainsearchlist'] = $_POST['domainsearchlist'];
600 6d53301b Jose Luis Duran
		$dhcpdconf['ignorebootp'] = ($_POST['ignorebootp']) ? true : false;
601 cba980f6 jim-p
		$dhcpdconf['denyunknown'] = ($_POST['denyunknown']) ? true : false;
602 11ee0c6d Brett Keller
		$dhcpdconf['ignoreclientuids'] = ($_POST['ignoreclientuids']) ? true : false;
603 3475eb04 Andrew Pilloud
		$dhcpdconf['nonak'] = ($_POST['nonak']) ? true : false;
604 cba980f6 jim-p
		$dhcpdconf['ddnsdomain'] = $_POST['ddnsdomain'];
605 87019fc4 Andres Petralli
		$dhcpdconf['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
606
		$dhcpdconf['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
607 534d7d69 Joeri Capens
		$dhcpdconf['ddnsdomainkeyalgorithm'] = $_POST['ddnsdomainkeyalgorithm'];
608 87019fc4 Andres Petralli
		$dhcpdconf['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
609 cba980f6 jim-p
		$dhcpdconf['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
610 cf15bcb4 Ross Williams
		$dhcpdconf['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
611 cba980f6 jim-p
		$dhcpdconf['mac_allow'] = $_POST['mac_allow'];
612
		$dhcpdconf['mac_deny'] = $_POST['mac_deny'];
613 67784aa6 Steve Beaver
		$dhcpdconf['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
614 cba980f6 jim-p
615
		unset($dhcpdconf['ntpserver']);
616 8f8682f7 Phil Davis
		if ($_POST['ntp1']) {
617 cba980f6 jim-p
			$dhcpdconf['ntpserver'][] = $_POST['ntp1'];
618 8f8682f7 Phil Davis
		}
619
		if ($_POST['ntp2']) {
620 cba980f6 jim-p
			$dhcpdconf['ntpserver'][] = $_POST['ntp2'];
621 8f8682f7 Phil Davis
		}
622 ad171999 Seth Mos
623 cba980f6 jim-p
		$dhcpdconf['tftp'] = $_POST['tftp'];
624
		$dhcpdconf['ldap'] = $_POST['ldap'];
625
		$dhcpdconf['netboot'] = ($_POST['netboot']) ? true : false;
626
		$dhcpdconf['nextserver'] = $_POST['nextserver'];
627
		$dhcpdconf['filename'] = $_POST['filename'];
628 7023c602 Charlie Root
		$dhcpdconf['filename32'] = $_POST['filename32'];
629
		$dhcpdconf['filename64'] = $_POST['filename64'];
630 cba980f6 jim-p
		$dhcpdconf['rootpath'] = $_POST['rootpath'];
631 18d316a5 heper
		unset($dhcpdconf['statsgraph']);
632
		if ($_POST['statsgraph']) {
633
			$dhcpdconf['statsgraph'] = $_POST['statsgraph'];
634 6303601e heper
			enable_rrd_graphing();
635 18d316a5 heper
		}
636 9c748b70 Scott Ullrich
637 d72b4114 Scott Ullrich
		// Handle the custom options rowhelper
638 8f8682f7 Phil Davis
		if (isset($dhcpdconf['numberoptions']['item'])) {
639 cba980f6 jim-p
			unset($dhcpdconf['numberoptions']['item']);
640 8f8682f7 Phil Davis
		}
641 6d1af0e9 jim-p
642 cba980f6 jim-p
		$dhcpdconf['numberoptions'] = $numberoptions;
643
644
		if (is_numeric($pool) && is_array($a_pools[$pool])) {
645
			$a_pools[$pool] = $dhcpdconf;
646
		} elseif ($act == "newpool") {
647
			$a_pools[] = $dhcpdconf;
648
		} else {
649
			$config['dhcpd'][$if] = $dhcpdconf;
650
		}
651 518030b3 Scott Ullrich
652 5b237745 Scott Ullrich
		write_config();
653 565488c9 Renato Botelho
	}
654
}
655 80933129 Bill Marquette
656 141d8913 jim-p
if ((isset($_POST['save']) || isset($_POST['apply'])) && (!$input_errors)) {
657 44c42356 Phil Davis
	$changes_applied = true;
658 565488c9 Renato Botelho
	$retval = 0;
659
	$retvaldhcp = 0;
660
	$retvaldns = 0;
661
	/* dnsmasq_configure calls dhcpd_configure */
662
	/* no need to restart dhcpd twice */
663
	if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic']))	{
664 44c42356 Phil Davis
		$retvaldns |= services_dnsmasq_configure();
665 565488c9 Renato Botelho
		if ($retvaldns == 0) {
666
			clear_subsystem_dirty('hosts');
667
			clear_subsystem_dirty('staticmaps');
668 de792e62 jim-p
		}
669 565488c9 Renato Botelho
	} else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) {
670 44c42356 Phil Davis
		$retvaldns |= services_unbound_configure();
671 4230ad16 Phil Davis
		if ($retvaldns == 0) {
672 565488c9 Renato Botelho
			clear_subsystem_dirty('unbound');
673 d3801fdb Renato Botelho
			clear_subsystem_dirty('hosts');
674
			clear_subsystem_dirty('staticmaps');
675 4230ad16 Phil Davis
		}
676 565488c9 Renato Botelho
	} else {
677 44c42356 Phil Davis
		$retvaldhcp |= services_dhcpd_configure();
678 8f8682f7 Phil Davis
		if ($retvaldhcp == 0) {
679 565488c9 Renato Botelho
			clear_subsystem_dirty('staticmaps');
680 8f8682f7 Phil Davis
		}
681 5b237745 Scott Ullrich
	}
682 a207d2c9 doktornotor
	/* BIND package - Bug #3710 */
683
	if (!function_exists('is_package_installed')) {
684
		require_once('pkg-utils.inc');
685
	}
686
	if (is_package_installed('pfSense-pkg-bind') && isset($config['installedpackages']['bind']['config'][0]['enable_bind'])) {
687
		$reloadbind = false;
688
		if (is_array($config['installedpackages']['bindzone'])) {
689
			$bindzone = $config['installedpackages']['bindzone']['config'];
690
		} else {
691
			$bindzone = array();
692
		}
693
		for ($x = 0; $x < sizeof($bindzone); $x++) {
694 e3d5c2e9 doktornotor
			$zone = $bindzone[$x];
695 a207d2c9 doktornotor
			if ($zone['regdhcpstatic'] == 'on') {
696
				$reloadbind = true;
697
				break;
698
			}
699
		}
700
		if ($reloadbind === true) {
701
			if (file_exists("/usr/local/pkg/bind.inc")) {
702
				require_once("/usr/local/pkg/bind.inc");
703
				bind_sync();
704
			}
705
		}
706
	}
707 8f8682f7 Phil Davis
	if ($dhcpd_enable_changed) {
708 44c42356 Phil Davis
		$retvalfc |= filter_configure();
709 8f8682f7 Phil Davis
	}
710 565488c9 Renato Botelho
711 8f8682f7 Phil Davis
	if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) {
712 565488c9 Renato Botelho
		$retval = 1;
713 8f8682f7 Phil Davis
	}
714 5b237745 Scott Ullrich
}
715
716 cba980f6 jim-p
if ($act == "delpool") {
717 c946d721 Steve Beaver
	if ($a_pools[$_POST['id']]) {
718
		unset($a_pools[$_POST['id']]);
719 cba980f6 jim-p
		write_config();
720
		header("Location: services_dhcp.php?if={$if}");
721
		exit;
722
	}
723
}
724
725
if ($act == "del") {
726 c946d721 Steve Beaver
	if (isset($a_maps[$_POST['id']])) {
727 fbb78d6b Phil Davis
		/* Remove static ARP entry, if necessary */
728 c946d721 Steve Beaver
		if (isset($a_maps[$_POST['id']]['arp_table_static_entry'])) {
729
			mwexec("/usr/sbin/arp -d " . escapeshellarg($a_maps[$_POST['id']]['ipaddr']));
730 632e5f50 jim-p
		}
731 c946d721 Steve Beaver
		unset($a_maps[$_POST['id']]);
732 5b237745 Scott Ullrich
		write_config();
733 8f8682f7 Phil Davis
		if (isset($config['dhcpd'][$if]['enable'])) {
734 a368a026 Ermal Lu?i
			mark_subsystem_dirty('staticmaps');
735 8f8682f7 Phil Davis
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic'])) {
736 a368a026 Ermal Lu?i
				mark_subsystem_dirty('hosts');
737 8f8682f7 Phil Davis
			}
738 6a01ea44 Bill Marquette
		}
739 b5f6e690 Stephen Beaver
740 5b237745 Scott Ullrich
		header("Location: services_dhcp.php?if={$if}");
741
		exit;
742
	}
743
}
744 4df96eff Scott Ullrich
745 3c9befb9 Chris Buechler
// Build an HTML table that can be inserted into a Form_StaticText element
746 b5f6e690 Stephen Beaver
function build_pooltable() {
747 96ab6943 Chris Buechler
	global $a_pools, $if;
748 b5f6e690 Stephen Beaver
749
	$pooltbl =	'<div class="table-responsive">';
750
	$pooltbl .=		'<table class="table table-striped table-hover table-condensed">';
751
	$pooltbl .=			'<thead>';
752
	$pooltbl .=				'<tr>';
753
	$pooltbl .=					'<th>' . gettext("Pool Start") . '</th>';
754
	$pooltbl .=					'<th>' . gettext("Pool End") . '</th>';
755
	$pooltbl .=					'<th>' . gettext("Description") . '</th>';
756 d7d7820e Phil Davis
	$pooltbl .=					'<th>' . gettext("Actions") . '</th>';
757 b5f6e690 Stephen Beaver
	$pooltbl .=				'</tr>';
758
	$pooltbl .=			'</thead>';
759
	$pooltbl .=			'<tbody>';
760
761
	if (is_array($a_pools)) {
762
		$i = 0;
763
		foreach ($a_pools as $poolent) {
764
			if (!empty($poolent['range']['from']) && !empty($poolent['range']['to'])) {
765
				$pooltbl .= '<tr>';
766
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
767
							htmlspecialchars($poolent['range']['from']) . '</td>';
768
769
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
770
							htmlspecialchars($poolent['range']['to']) . '</td>';
771
772
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
773
							htmlspecialchars($poolent['descr']) . '</td>';
774
775 d7d7820e Phil Davis
				$pooltbl .= '<td><a class="fa fa-pencil" title="'. gettext("Edit pool") . '" href="services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '"></a>';
776 b5f6e690 Stephen Beaver
777 c946d721 Steve Beaver
				$pooltbl .= ' <a class="fa fa-trash" title="'. gettext("Delete pool") . '" href="services_dhcp.php?if=' . htmlspecialchars($if) . '&act=delpool&id=' . $i . '" usepost></a></td>';
778 b5f6e690 Stephen Beaver
				$pooltbl .= '</tr>';
779
			}
780
		$i++;
781
		}
782
	}
783
784
	$pooltbl .=			'</tbody>';
785
	$pooltbl .=		'</table>';
786
	$pooltbl .= '</div>';
787
788
	return($pooltbl);
789
}
790
791 bf27317d Phil Davis
$pgtitle = array(gettext("Services"), gettext("DHCP Server"));
792 edcd7535 Phil Davis
$pglinks = array("", "services_dhcp.php");
793 fa94122b k-paulius
794 48614394 Phil Davis
if (!empty($if) && isset($iflist[$if])) {
795 fa94122b k-paulius
	$pgtitle[] = $iflist[$if];
796 edcd7535 Phil Davis
	$pglinks[] = "@self";
797 fa94122b k-paulius
}
798 b32dd0a6 jim-p
$shortcut_section = "dhcp";
799 5224b8e7 jim-p
800 4df96eff Scott Ullrich
include("head.inc");
801
802 6e3488e9 Phil Davis
if ($input_errors) {
803 b5f6e690 Stephen Beaver
	print_input_errors($input_errors);
804 6e3488e9 Phil Davis
}
805 4df96eff Scott Ullrich
806 44c42356 Phil Davis
if ($changes_applied) {
807
	print_apply_result_box($retval);
808 6e3488e9 Phil Davis
}
809 678dfd0f Erik Fonnesbeck
810 6e3488e9 Phil Davis
if (is_subsystem_dirty('staticmaps')) {
811 5daef710 NOYB
	print_apply_box(gettext("The static mapping configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect."));
812 6e3488e9 Phil Davis
}
813 b5f6e690 Stephen Beaver
814
/* active tabs */
815
$tab_array = array();
816
$tabscounter = 0;
817
$i = 0;
818 b7090449 Phil Davis
$have_small_subnet = false;
819 8a73f407 Stephen Beaver
820 b5f6e690 Stephen Beaver
foreach ($iflist as $ifent => $ifname) {
821
	$oc = $config['interfaces'][$ifent];
822 403dad2a Renato Botelho
823
	/* Not static IPv4 or subnet >= 31 */
824 b7090449 Phil Davis
	if ($oc['subnet'] >= 31) {
825
		$have_small_subnet = true;
826 12e08722 Phil Davis
		$example_name = $ifname;
827
		$example_cidr = $oc['subnet'];
828 b7090449 Phil Davis
		continue;
829
	}
830
	if (!is_ipaddrv4($oc['ipaddr']) || empty($oc['subnet'])) {
831 b5f6e690 Stephen Beaver
		continue;
832 518030b3 Scott Ullrich
	}
833 4e9cd828 Seth Mos
834 b5f6e690 Stephen Beaver
	if ($ifent == $if) {
835
		$active = true;
836
	} else {
837
		$active = false;
838 b1d132f5 Scott Ullrich
	}
839
840 b5f6e690 Stephen Beaver
	$tab_array[] = array($ifname, $active, "services_dhcp.php?if={$ifent}");
841
	$tabscounter++;
842
}
843 ad171999 Seth Mos
844 b5f6e690 Stephen Beaver
if ($tabscounter == 0) {
845 b7090449 Phil Davis
	if ($have_small_subnet) {
846 12e08722 Phil Davis
		$sentence2 = sprintf(gettext('%1$s has a CIDR mask of %2$s, which does not contain enough addresses.'), htmlspecialchars($example_name), htmlspecialchars($example_cidr));
847 b7090449 Phil Davis
	} else {
848 12e08722 Phil Davis
		$sentence2 = gettext("This system has no interfaces configured with a static IPv4 address.");
849 b7090449 Phil Davis
	}
850 12e08722 Phil Davis
	print_info_box(gettext("The DHCP Server requires a static IPv4 subnet large enough to serve addresses to clients.") . " " . $sentence2);
851 b5f6e690 Stephen Beaver
	include("foot.inc");
852
	exit;
853
}
854 1f1a08c8 jim-p
855 b5f6e690 Stephen Beaver
display_top_tabs($tab_array);
856
857 8f58b51b jim-p
$form = new Form();
858 b5f6e690 Stephen Beaver
859
$section = new Form_Section('General Options');
860
861
if (!is_numeric($pool) && !($act == "newpool")) {
862 48614394 Phil Davis
	if (isset($config['dhcrelay']['enable'])) {
863
		$section->addInput(new Form_Checkbox(
864
			'enable',
865
			'Enable',
866
			gettext("DHCP Relay is currently enabled. DHCP Server canot be enabled while the DHCP Relay is enabled on any interface."),
867
			$pconfig['enable']
868
		))->setAttribute('disabled', true);
869
	} else {
870
		$section->addInput(new Form_Checkbox(
871
			'enable',
872
			'Enable',
873
			sprintf(gettext("Enable DHCP server on %s interface"), htmlspecialchars($iflist[$if])),
874
			$pconfig['enable']
875
		));
876
	}
877 b5f6e690 Stephen Beaver
} else {
878 02342d8c k-paulius
	print_info_box(gettext('Editing pool-specific options. To return to the Interface, click its tab above.'), 'info', false);
879 b5f6e690 Stephen Beaver
}
880 6c23757b Martin Fuchs
881 6d53301b Jose Luis Duran
$section->addInput(new Form_Checkbox(
882
	'ignorebootp',
883
	'BOOTP',
884
	'Ignore BOOTP queries',
885
	$pconfig['ignorebootp']
886
));
887
888 b5f6e690 Stephen Beaver
$section->addInput(new Form_Checkbox(
889
	'denyunknown',
890
	'Deny unknown clients',
891
	'Only the clients defined below will get DHCP leases from this server.',
892
	$pconfig['denyunknown']
893
));
894
895 3475eb04 Andrew Pilloud
$section->addInput(new Form_Checkbox(
896
	'nonak',
897
	'Ignore denied clients',
898
	'Denied clients will be ignored rather than rejected.',
899
	$pconfig['nonak']
900 8209517d jim-p
))->setHelp("This option is not compatible with failover and cannot be enabled when a Failover Peer IP address is configured.");
901 3475eb04 Andrew Pilloud
902 11ee0c6d Brett Keller
$section->addInput(new Form_Checkbox(
903
	'ignoreclientuids',
904
	'Ignore client identifiers',
905
	'If a client includes a unique identifier in its DHCP request, that UID will not be recorded in its lease.',
906
	$pconfig['ignoreclientuids']
907
))->setHelp("This option may be useful when a client can dual boot using different client identifiers but the same hardware (MAC) address.  Note that the resulting server behavior violates the official DHCP specification.");
908
909 3475eb04 Andrew Pilloud
910 b5f6e690 Stephen Beaver
if (is_numeric($pool) || ($act == "newpool")) {
911
	$section->addInput(new Form_Input(
912
		'descr',
913
		'Pool Description',
914
		'text',
915
		$pconfig['descr']
916
	));
917
}
918 6c23757b Martin Fuchs
919 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
920
	'Subnet',
921
	gen_subnet($ifcfgip, $ifcfgsn)
922
));
923 4e9cd828 Seth Mos
924 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
925
	'Subnet mask',
926
	gen_subnet_mask($ifcfgsn)
927
));
928 5b237745 Scott Ullrich
929 8a73f407 Stephen Beaver
// Compose a string to display the required address ranges
930 b90d635e Renato Botelho
$rangestr = ip_after($subnet_start) . ' - ' . ip_before($subnet_end);
931 b5f6e690 Stephen Beaver
932
if (is_numeric($pool) || ($act == "newpool")) {
933 4bb7c0d1 bruno
	$rangestr .= '<br />' . gettext('In-use DHCP Pool Ranges:');
934 b5f6e690 Stephen Beaver
	if (is_array($config['dhcpd'][$if]['range'])) {
935
		$rangestr .= '<br />' . $config['dhcpd'][$if]['range']['from'] . ' - ' . $config['dhcpd'][$if]['range']['to'];
936 3d7b7757 Chris Buechler
	}
937 b5f6e690 Stephen Beaver
938
	foreach ($a_pools as $p) {
939
		if (is_array($p['range'])) {
940
			$rangestr .= '<br />' . $p['range']['from'] . ' - ' . $p['range']['to'];
941 8f8682f7 Phil Davis
		}
942 934240ef Ermal Luçi
	}
943 b5f6e690 Stephen Beaver
}
944
945
$section->addInput(new Form_StaticText(
946
	'Available range',
947
	$rangestr
948
));
949
950
if ($is_olsr_enabled) {
951
	$section->addInput(new Form_Select(
952
		'netmask',
953
		'Subnet mask',
954
		$pconfig['netmask'],
955
		array_combine(range(32, 1, -1), range(32, 1, -1))
956
	));
957
}
958
959 24b82516 Phil Davis
$group = new Form_Group('*Range');
960 b5f6e690 Stephen Beaver
961
$group->add(new Form_IpAddress(
962
	'range_from',
963
	null,
964 eb01f065 Phil Davis
	$pconfig['range_from'],
965
	'V4'
966 b5f6e690 Stephen Beaver
))->setHelp('From');
967
968
$group->add(new Form_IpAddress(
969
	'range_to',
970
	null,
971 eb01f065 Phil Davis
	$pconfig['range_to'],
972
	'V4'
973 b5f6e690 Stephen Beaver
))->setHelp('To');
974
975
$section->add($group);
976
977
$form->add($section);
978
979
if (!is_numeric($pool) && !($act == "newpool")) {
980 5f88f964 k-paulius
	$section = new Form_Section('Additional Pools');
981 b5f6e690 Stephen Beaver
982
	$btnaddpool = new Form_Button(
983
		'btnaddpool',
984 faab522f Renato Botelho
		'Add pool',
985 37676f4e jim-p
		'services_dhcp.php?if=' . htmlspecialchars($if) . '&act=newpool',
986
		'fa-plus'
987 b5f6e690 Stephen Beaver
	);
988 37676f4e jim-p
	$btnaddpool->addClass('btn-success');
989 b5f6e690 Stephen Beaver
990
	$section->addInput(new Form_StaticText(
991
		'Add',
992
		$btnaddpool
993 e78ecb96 NOYB
	))->setHelp('If additional pools of addresses are needed inside of this subnet outside the above Range, they may be specified here.');
994 b5f6e690 Stephen Beaver
995
	if (is_array($a_pools)) {
996
		$section->addInput(new Form_StaticText(
997
			null,
998
			build_pooltable()
999
		));
1000 f0cdf141 Scott Ullrich
	}
1001 b5f6e690 Stephen Beaver
1002
	$form->add($section);
1003
}
1004
1005
$section = new Form_Section('Servers');
1006
1007
$section->addInput(new Form_IpAddress(
1008
	'wins1',
1009
	'WINS servers',
1010 eb01f065 Phil Davis
	$pconfig['wins1'],
1011
	'V4'
1012
))->setAttribute('placeholder', 'WINS Server 1');
1013 b5f6e690 Stephen Beaver
1014
$section->addInput(new Form_IpAddress(
1015
	'wins2',
1016
	null,
1017 eb01f065 Phil Davis
	$pconfig['wins2'],
1018
	'V4'
1019
))->setAttribute('placeholder', 'WINS Server 2');
1020 b5f6e690 Stephen Beaver
1021 6e3488e9 Phil Davis
for ($idx=1; $idx<=4; $idx++) {
1022 b5f6e690 Stephen Beaver
	$section->addInput(new Form_IpAddress(
1023
		'dns' . $idx,
1024
		($idx == 1) ? 'DNS servers':null,
1025 eb01f065 Phil Davis
		$pconfig['dns' . $idx],
1026
		'V4'
1027
	))->setAttribute('placeholder', 'DNS Server ' . $idx)->setHelp(($idx == 4) ? 'Leave blank to use the system default DNS servers: this interface\'s IP if DNS Forwarder or Resolver is enabled, otherwise the servers configured on the System / General Setup page.':'');
1028 b5f6e690 Stephen Beaver
}
1029
1030
$form->add($section);
1031
1032 5f88f964 k-paulius
$section = new Form_Section('Other Options');
1033 b5f6e690 Stephen Beaver
1034
$section->addInput(new Form_IpAddress(
1035
	'gateway',
1036
	'Gateway',
1037 eb01f065 Phil Davis
	$pconfig['gateway'],
1038
	'V4'
1039 b5f6e690 Stephen Beaver
))->setPattern('[.a-zA-Z0-9_]+')
1040 e78ecb96 NOYB
  ->setHelp('The default is to use the IP on this interface of the firewall as the gateway. Specify an alternate gateway here if this is not the correct gateway for the network. Type "none" for no gateway assignment.');
1041 b5f6e690 Stephen Beaver
1042
$section->addInput(new Form_Input(
1043
	'domain',
1044
	'Domain name',
1045
	'text',
1046
	$pconfig['domain']
1047 e78ecb96 NOYB
))->setHelp('The default is to use the domain name of this system as the default domain name provided by DHCP. An alternate domain name may be specified here.');
1048 b5f6e690 Stephen Beaver
1049
$section->addInput(new Form_Input(
1050
	'domainsearchlist',
1051
	'Domain search list',
1052
	'text',
1053
	$pconfig['domainsearchlist']
1054 e78ecb96 NOYB
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
1055 b5f6e690 Stephen Beaver
1056
$section->addInput(new Form_Input(
1057
	'deftime',
1058
	'Default lease time',
1059
	'number',
1060
	$pconfig['deftime']
1061 e78ecb96 NOYB
))->setHelp('This is used for clients that do not ask for a specific expiration time. The default is 7200 seconds.');
1062 b5f6e690 Stephen Beaver
1063
$section->addInput(new Form_Input(
1064
	'maxtime',
1065
	'Maximum lease time',
1066
	'number',
1067
	$pconfig['maxtime']
1068 e78ecb96 NOYB
))->setHelp('This is the maximum lease time for clients that ask for a specific expiration time. The default is 86400 seconds.');
1069 b5f6e690 Stephen Beaver
1070
if (!is_numeric($pool) && !($act == "newpool")) {
1071
	$section->addInput(new Form_IpAddress(
1072
		'failover_peerip',
1073
		'Failover peer IP',
1074 eb01f065 Phil Davis
		$pconfig['failover_peerip'],
1075
		'V4'
1076 af8f79b1 Chris Buechler
	))->setHelp('Leave blank to disable. Enter the interface IP address of the other machine. Machines must be using CARP. ' .
1077 4c1284c6 NOYB
				'Interface\'s advskew determines whether the DHCPd process is Primary or Secondary. Ensure one machine\'s advskew &lt; 20 (and the other is &gt; 20).');
1078 b5f6e690 Stephen Beaver
}
1079
1080
if (!is_numeric($pool) && !($act == "newpool")) {
1081
	$section->addInput(new Form_Checkbox(
1082
		'staticarp',
1083
		'Static ARP',
1084
		'Enable Static ARP entries',
1085
		$pconfig['staticarp']
1086 0c8d2784 Chris Buechler
	))->setHelp('This option persists even if DHCP server is disabled. Only the machines listed below will be able to communicate with the firewall on this interface.');
1087 b5f6e690 Stephen Beaver
1088
	$section->addInput(new Form_Checkbox(
1089
		'dhcpleaseinlocaltime',
1090
		'Time format change',
1091
		'Change DHCP display lease time from UTC to local time',
1092
		$pconfig['dhcpleaseinlocaltime']
1093
	))->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.' .
1094 e78ecb96 NOYB
				' This will be used for all DHCP interfaces lease time.');
1095 18d316a5 heper
	$section->addInput(new Form_Checkbox(
1096
		'statsgraph',
1097 61237194 Chris Buechler
		'Statistics graphs',
1098
		'Enable RRD statistics graphs',
1099 18d316a5 heper
		$pconfig['statsgraph']
1100 61237194 Chris Buechler
	))->setHelp('Enable this to add DHCP leases statistics to the RRD graphs. Disabled by default.');
1101 b5f6e690 Stephen Beaver
}
1102
1103
// DDNS
1104
$btnadv = new Form_Button(
1105
	'btnadvdns',
1106 afe62c2b Phil Davis
	'Display Advanced',
1107 3314e626 jim-p
	null,
1108
	'fa-cog'
1109 b5f6e690 Stephen Beaver
);
1110
1111 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1112 b5f6e690 Stephen Beaver
1113
$section->addInput(new Form_StaticText(
1114
	'Dynamic DNS',
1115
	$btnadv
1116
));
1117
1118
$section->addInput(new Form_Checkbox(
1119
	'ddnsupdate',
1120
	null,
1121
	'Enable registration of DHCP client names in DNS',
1122
	$pconfig['ddnsupdate']
1123
));
1124
1125
$section->addInput(new Form_Input(
1126
	'ddnsdomain',
1127
	'DDNS Domain',
1128 e8da0bcd Jeremy Porter
	'text',
1129 b5f6e690 Stephen Beaver
	$pconfig['ddnsdomain']
1130 e5c4b4fc Joeri Capens
))->setHelp('Enter the dynamic DNS domain which will be used to register client names in the DNS server.');
1131 b5f6e690 Stephen Beaver
1132 cf15bcb4 Ross Williams
$section->addInput(new Form_Checkbox(
1133
	'ddnsforcehostname',
1134 cfc10a33 Ross Williams
	'DDNS Hostnames',
1135 cf15bcb4 Ross Williams
	'Force dynamic DNS hostname to be the same as configured hostname for Static Mappings',
1136
	$pconfig['ddnsforcehostname']
1137 9ca5d4ab Ross Williams
))->setHelp('Default registers host name option supplied by DHCP client.');
1138 cf15bcb4 Ross Williams
1139 b5f6e690 Stephen Beaver
$section->addInput(new Form_IpAddress(
1140
	'ddnsdomainprimary',
1141
	'Primary DDNS address',
1142 eb01f065 Phil Davis
	$pconfig['ddnsdomainprimary'],
1143
	'V4'
1144 cb6c20a9 NewEraCracker
))->setHelp('Primary domain name server IP address for the dynamic domain name.');
1145 b5f6e690 Stephen Beaver
1146
$section->addInput(new Form_Input(
1147
	'ddnsdomainkeyname',
1148
	'DNS Domain key',
1149
	'text',
1150
	$pconfig['ddnsdomainkeyname']
1151 cb6c20a9 NewEraCracker
))->setHelp('Dynamic DNS domain key name which will be used to register client names in the DNS server.');
1152 b5f6e690 Stephen Beaver
1153 534d7d69 Joeri Capens
$section->addInput(new Form_Select(
1154
	'ddnsdomainkeyalgorithm',
1155
	'Key algorithm',
1156
	$pconfig['ddnsdomainkeyalgorithm'],
1157
	array(
1158
		'hmac-md5' => 'HMAC-MD5 (legacy default)',
1159
		'hmac-sha1' => 'HMAC-SHA1',
1160
		'hmac-sha224' => 'HMAC-SHA224',
1161
		'hmac-sha256' => 'HMAC-SHA256 (current bind9 default)',
1162
		'hmac-sha384' => 'HMAC-SHA384',
1163
		'hmac-sha512' => 'HMAC-SHA512 (most secure)',
1164
	)
1165
));
1166
1167 b5f6e690 Stephen Beaver
$section->addInput(new Form_Input(
1168
	'ddnsdomainkey',
1169
	'DNS Domain key secret',
1170
	'text',
1171
	$pconfig['ddnsdomainkey']
1172 e5c4b4fc Joeri Capens
))->setHelp('Dynamic DNS domain key secret which will be used to register client names in the DNS server.');
1173 b5f6e690 Stephen Beaver
1174 67784aa6 Steve Beaver
$section->addInput(new Form_Select(
1175
	'ddnsclientupdates',
1176
	'DDNS Client Updates',
1177
	$pconfig['ddnsclientupdates'],
1178
	array(
1179
	    'allow' => gettext('Allow'),
1180
	    'deny' => gettext('Deny'),
1181
	    'ignore' => gettext('Ignore'))
1182
))->setHelp('How Forward entries are handled when client indicates they wish to update DNS.  ' .
1183
	    'Allow prevents DHCP from updating Forward entries, Deny indicates that DHCP will ' .
1184
	    'do the updates and the client should not, Ignore specifies that DHCP will do the ' .
1185
	    'update and the client can also attempt the update usually using a different domain name.');
1186
1187 b5f6e690 Stephen Beaver
// Advanced MAC
1188
$btnadv = new Form_Button(
1189
	'btnadvmac',
1190 afe62c2b Phil Davis
	'Display Advanced',
1191 3314e626 jim-p
	null,
1192
	'fa-cog'
1193 b5f6e690 Stephen Beaver
);
1194
1195 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1196 b5f6e690 Stephen Beaver
1197
$section->addInput(new Form_StaticText(
1198
	'MAC address control',
1199
	$btnadv
1200
));
1201
1202
$section->addInput(new Form_Input(
1203
	'mac_allow',
1204 ef2936e6 Stephen Beaver
	'MAC Allow',
1205 b5f6e690 Stephen Beaver
	'text',
1206
	$pconfig['mac_allow']
1207
))->setHelp('List of partial MAC addresses to allow, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1208
1209
$section->addInput(new Form_Input(
1210
	'mac_deny',
1211 ef2936e6 Stephen Beaver
	'MAC Deny',
1212 b5f6e690 Stephen Beaver
	'text',
1213
	$pconfig['mac_deny']
1214
))->setHelp('List of partial MAC addresses to deny access, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1215
1216
// Advanced NTP
1217
$btnadv = new Form_Button(
1218
	'btnadvntp',
1219 afe62c2b Phil Davis
	'Display Advanced',
1220 3314e626 jim-p
	null,
1221
	'fa-cog'
1222 b5f6e690 Stephen Beaver
);
1223
1224 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1225 b5f6e690 Stephen Beaver
1226
$section->addInput(new Form_StaticText(
1227 ff3da1e7 Stephen Beaver
	'NTP',
1228 b5f6e690 Stephen Beaver
	$btnadv
1229
));
1230
1231
$section->addInput(new Form_IpAddress(
1232
	'ntp1',
1233 ff3da1e7 Stephen Beaver
	'NTP Server 1',
1234 eb01f065 Phil Davis
	$pconfig['ntp1'],
1235 45541aae Phil Davis
	'HOSTV4'
1236
));
1237 b5f6e690 Stephen Beaver
1238
$section->addInput(new Form_IpAddress(
1239
	'ntp2',
1240 ff3da1e7 Stephen Beaver
	'NTP Server 2',
1241 eb01f065 Phil Davis
	$pconfig['ntp2'],
1242 45541aae Phil Davis
	'HOSTV4'
1243
));
1244 b5f6e690 Stephen Beaver
1245
// Advanced TFTP
1246
$btnadv = new Form_Button(
1247
	'btnadvtftp',
1248 afe62c2b Phil Davis
	'Display Advanced',
1249 3314e626 jim-p
	null,
1250
	'fa-cog'
1251 b5f6e690 Stephen Beaver
);
1252
1253 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1254 b5f6e690 Stephen Beaver
1255
$section->addInput(new Form_StaticText(
1256 ff3da1e7 Stephen Beaver
	'TFTP',
1257 b5f6e690 Stephen Beaver
	$btnadv
1258
));
1259
1260 c411661a doktornotor
$section->addInput(new Form_Input(
1261 b5f6e690 Stephen Beaver
	'tftp',
1262 ff3da1e7 Stephen Beaver
	'TFTP Server',
1263 9d9736d7 jim-p
	'text',
1264 b5f6e690 Stephen Beaver
	$pconfig['tftp']
1265 c411661a doktornotor
))->setHelp('Leave blank to disable. Enter a valid IP address, hostname or URL for the TFTP server.');
1266 b5f6e690 Stephen Beaver
1267
// Advanced LDAP
1268
$btnadv = new Form_Button(
1269
	'btnadvldap',
1270 afe62c2b Phil Davis
	'Display Advanced',
1271 3314e626 jim-p
	null,
1272
	'fa-cog'
1273 b5f6e690 Stephen Beaver
);
1274
1275 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1276 b5f6e690 Stephen Beaver
1277
$section->addInput(new Form_StaticText(
1278 ff3da1e7 Stephen Beaver
	'LDAP',
1279 b5f6e690 Stephen Beaver
	$btnadv
1280
));
1281
1282
$section->addInput(new Form_Input(
1283
	'ldap',
1284 ff3da1e7 Stephen Beaver
	'LDAP Server URI',
1285 b5f6e690 Stephen Beaver
	'text',
1286
	$pconfig['ldap']
1287
))->setHelp('Leave blank to disable. Enter a full URI for the LDAP server in the form ldap://ldap.example.com/dc=example,dc=com ');
1288
1289 68de2169 Phil Davis
// Advanced Network Booting options
1290
$btnadv = new Form_Button(
1291
	'btnadvnwkboot',
1292
	'Display Advanced',
1293
	null,
1294
	'fa-cog'
1295
);
1296
1297
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1298
1299
$section->addInput(new Form_StaticText(
1300
	'Network Booting',
1301
	$btnadv
1302
));
1303
1304
$section->addInput(new Form_Checkbox(
1305
	'netboot',
1306
	'Enable',
1307
	'Enables network booting',
1308
	$pconfig['netboot']
1309
));
1310
1311
$section->addInput(new Form_IpAddress(
1312
	'nextserver',
1313
	'Next Server',
1314 eb01f065 Phil Davis
	$pconfig['nextserver'],
1315
	'V4'
1316 68de2169 Phil Davis
))->setHelp('Enter the IP address of the next server');
1317
1318
$section->addInput(new Form_Input(
1319
	'filename',
1320
	'Default BIOS file name',
1321
	'text',
1322
	$pconfig['filename']
1323
));
1324
1325
$section->addInput(new Form_Input(
1326
	'filename32',
1327
	'UEFI 32 bit file name',
1328
	'text',
1329
	$pconfig['filename32']
1330
));
1331
1332
$section->addInput(new Form_Input(
1333
	'filename64',
1334
	'UEFI 64 bit file name',
1335
	'text',
1336
	$pconfig['filename64']
1337
))->setHelp('Both a filename and a boot server must be configured for this to work! ' .
1338
			'All three filenames and a configured boot server are necessary for UEFI to work! ');
1339
1340
$section->addInput(new Form_Input(
1341
	'rootpath',
1342
	'Root path',
1343
	'text',
1344
	$pconfig['rootpath']
1345
))->setHelp('string-format: iscsi:(servername):(protocol):(port):(LUN):targetname ');
1346
1347 b5f6e690 Stephen Beaver
// Advanced Additional options
1348
$btnadv = new Form_Button(
1349
	'btnadvopts',
1350 afe62c2b Phil Davis
	'Display Advanced',
1351 3314e626 jim-p
	null,
1352
	'fa-cog'
1353 b5f6e690 Stephen Beaver
);
1354
1355 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1356 b5f6e690 Stephen Beaver
1357
$section->addInput(new Form_StaticText(
1358
	'Additional BOOTP/DHCP Options',
1359
	$btnadv
1360
));
1361
1362 f8088b00 Phil Davis
$form->add($section);
1363
1364 b5f6e690 Stephen Beaver
$section = new Form_Section('Additional BOOTP/DHCP Options');
1365
$section->addClass('adnlopts');
1366
1367
$section->addInput(new Form_StaticText(
1368
	null,
1369 5daef710 NOYB
	'<div class="alert alert-info"> ' . gettext('Enter the DHCP option number and the value for each item to include in the DHCP lease information.') . ' ' .
1370 3fd41815 Phil Davis
	sprintf(gettext('For a list of available options please visit this %1$s URL%2$s.%3$s'), '<a href="http://www.iana.org/assignments/bootp-dhcp-parameters/" target="_blank">', '</a>', '</div>')
1371 b5f6e690 Stephen Beaver
));
1372
1373 6e3488e9 Phil Davis
if (!$pconfig['numberoptions']) {
1374 f156083a Steve Beaver
	$pconfig['numberoptions'] = array();
1375 b5f6e690 Stephen Beaver
	$pconfig['numberoptions']['item']  = array(array('number' => '', 'type' => 'text', 'value' => ''));
1376
}
1377
1378
$customitemtypes = array(
1379
	'text' => gettext('Text'), 'string' => gettext('String'), 'boolean' => gettext('Boolean'),
1380
	'unsigned integer 8' => gettext('Unsigned 8-bit integer'), 'unsigned integer 16' => gettext('Unsigned 16-bit integer'), 'unsigned integer 32' => gettext('Unsigned 32-bit integer'),
1381
	'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')
1382
);
1383
1384
$numrows = count($item) -1;
1385
$counter = 0;
1386
1387
$numrows = count($pconfig['numberoptions']['item']) -1;
1388
1389
foreach ($pconfig['numberoptions']['item'] as $item) {
1390
	$number = $item['number'];
1391
	$itemtype = $item['type'];
1392 65cce9d7 Renato Botelho
	$value = base64_decode($item['value']);
1393 b5f6e690 Stephen Beaver
1394
	$group = new Form_Group(($counter == 0) ? 'Option':null);
1395
	$group->addClass('repeatable');
1396
1397
	$group->add(new Form_Input(
1398
		'number' . $counter,
1399
		null,
1400 60682dd2 Michael Newton
		'number',
1401
		$number,
1402
		['min'=>'1', 'max'=>'254']
1403 b5f6e690 Stephen Beaver
	))->setHelp($numrows == $counter ? 'Number':null);
1404
1405
1406
	$group->add(new Form_Select(
1407
		'itemtype' . $counter,
1408
		null,
1409
		$itemtype,
1410
		$customitemtypes
1411 8a73f407 Stephen Beaver
	))->setWidth(3)->setHelp($numrows == $counter ? 'Type':null);
1412 b5f6e690 Stephen Beaver
1413
	$group->add(new Form_Input(
1414
		'value' . $counter,
1415
		null,
1416
		'text',
1417
		$value
1418
	))->setHelp($numrows == $counter ? 'Value':null);
1419
1420
	$group->add(new Form_Button(
1421
		'deleterow' . $counter,
1422 faab522f Renato Botelho
		'Delete',
1423 cd7ddae6 jim-p
		null,
1424
		'fa-trash'
1425
	))->addClass('btn-warning');
1426 b5f6e690 Stephen Beaver
1427
	$section->add($group);
1428
1429
	$counter++;
1430
}
1431
1432
$section->addInput(new Form_Button(
1433
	'addrow',
1434 faab522f Renato Botelho
	'Add',
1435 cd7ddae6 jim-p
	null,
1436
	'fa-plus'
1437
))->addClass('btn-success');
1438 b5f6e690 Stephen Beaver
1439
$form->add($section);
1440
1441
if ($act == "newpool") {
1442
	$form->addGlobal(new Form_Input(
1443
		'act',
1444
		null,
1445
		'hidden',
1446
		'newpool'
1447
	));
1448
}
1449
1450
if (is_numeric($pool)) {
1451
	$form->addGlobal(new Form_Input(
1452
		'pool',
1453
		null,
1454
		'hidden',
1455
		$pool
1456
	));
1457
}
1458
1459
$form->addGlobal(new Form_Input(
1460
	'if',
1461
	null,
1462
	'hidden',
1463
	$if
1464
));
1465
1466
print($form);
1467
1468
// DHCP Static Mappings table
1469
1470
if (!is_numeric($pool) && !($act == "newpool")) {
1471 6e3e95a5 Phil Davis
1472
	// Decide whether display of the Client Id column is needed.
1473
	$got_cid = false;
1474
	if (is_array($a_maps)) {
1475
		foreach ($a_maps as $map) {
1476
			if (!empty($map['cid'])) {
1477
				$got_cid = true;
1478
				break;
1479
			}
1480
		}
1481
	}
1482 de792e62 jim-p
?>
1483 b5f6e690 Stephen Beaver
1484
<div class="panel panel-default">
1485 3d7a8696 k-paulius
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCP Static Mappings for this Interface")?></h2></div>
1486 b5f6e690 Stephen Beaver
	<div class="table-responsive">
1487 55f67b5a Stephen Beaver
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
1488 b5f6e690 Stephen Beaver
				<thead>
1489
					<tr>
1490
						<th><?=gettext("Static ARP")?></th>
1491
						<th><?=gettext("MAC address")?></th>
1492 6e3e95a5 Phil Davis
<?php
1493
	if ($got_cid):
1494
?>
1495
						<th><?=gettext("Client Id")?></th>
1496
<?php
1497
	endif;
1498
?>
1499 b5f6e690 Stephen Beaver
						<th><?=gettext("IP address")?></th>
1500
						<th><?=gettext("Hostname")?></th>
1501
						<th><?=gettext("Description")?></th>
1502
						<th></th>
1503
					</tr>
1504
				</thead>
1505 8f8682f7 Phil Davis
<?php
1506 b5f6e690 Stephen Beaver
	if (is_array($a_maps)) {
1507
		$i = 0;
1508 8f8682f7 Phil Davis
?>
1509 b5f6e690 Stephen Beaver
				<tbody>
1510 8f8682f7 Phil Davis
<?php
1511 b5f6e690 Stephen Beaver
		foreach ($a_maps as $mapent) {
1512 8f8682f7 Phil Davis
?>
1513 b5f6e690 Stephen Beaver
					<tr>
1514 1d932e0c NOYB
						<td class="text-center" ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1515 b5f6e690 Stephen Beaver
							<?php if (isset($mapent['arp_table_static_entry'])): ?>
1516 1b7379f9 Jared Dillard
								<i class="fa fa-check"></i>
1517 b5f6e690 Stephen Beaver
							<?php endif; ?>
1518
						</td>
1519
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1520
							<?=htmlspecialchars($mapent['mac'])?>
1521
						</td>
1522 6e3e95a5 Phil Davis
<?php
1523
			if ($got_cid):
1524
?>
1525
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1526
							<?=htmlspecialchars($mapent['cid'])?>
1527
						</td>
1528
<?php
1529
			endif;
1530
?>
1531 b5f6e690 Stephen Beaver
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1532
							<?=htmlspecialchars($mapent['ipaddr'])?>
1533
						</td>
1534
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1535
							<?=htmlspecialchars($mapent['hostname'])?>
1536
						</td>
1537
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1538
							<?=htmlspecialchars($mapent['descr'])?>
1539
						</td>
1540
						<td>
1541 9a6a8329 heper
							<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>"	href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>"></a>
1542 c946d721 Steve Beaver
							<a class="fa fa-trash"	title="<?=gettext('Delete static mapping')?>"	href="services_dhcp.php?if=<?=htmlspecialchars($if)?>&amp;act=del&amp;id=<?=$i?>" usepost></a>
1543 b5f6e690 Stephen Beaver
						</td>
1544
					</tr>
1545 8f8682f7 Phil Davis
<?php
1546 b5f6e690 Stephen Beaver
		$i++;
1547
		}
1548 8f8682f7 Phil Davis
?>
1549 b5f6e690 Stephen Beaver
				</tbody>
1550 8f8682f7 Phil Davis
<?php
1551 b5f6e690 Stephen Beaver
	}
1552 8f8682f7 Phil Davis
?>
1553 82f54a42 Colin Fleming
		</table>
1554 b5f6e690 Stephen Beaver
	</div>
1555
</div>
1556 c9679d8c Stephen Beaver
1557 c10cb196 Stephen Beaver
<nav class="action-buttons">
1558 c9679d8c Stephen Beaver
	<a href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>" class="btn btn-sm btn-success">
1559 9d5a20cf heper
		<i class="fa fa-plus icon-embed-btn"></i>
1560 c9679d8c Stephen Beaver
		<?=gettext("Add")?>
1561
	</a>
1562
</nav>
1563 8f8682f7 Phil Davis
<?php
1564 b5f6e690 Stephen Beaver
}
1565 8f8682f7 Phil Davis
?>
1566
1567 8fd9052f Colin Fleming
<script type="text/javascript">
1568 b5f6e690 Stephen Beaver
//<![CDATA[
1569 6e3488e9 Phil Davis
events.push(function() {
1570 b5f6e690 Stephen Beaver
1571
	// Show advanced DNS options ======================================================================================
1572
	var showadvdns = false;
1573
1574 afe62c2b Phil Davis
	function show_advdns(ispageload) {
1575
		var text;
1576
		// On page load decide the initial state based on the data.
1577
		if (ispageload) {
1578 b5f6e690 Stephen Beaver
<?php
1579 67784aa6 Steve Beaver
			if (!$pconfig['ddnsupdate'] &&
1580
				!$pconfig['ddnsforcehostname'] &&
1581
				empty($pconfig['ddnsdomain']) &&
1582
				empty($pconfig['ddnsdomainprimary']) &&
1583
			    empty($pconfig['ddnsdomainkeyname']) &&
1584 3e1b29c7 Michael Alden
			    (empty($pconfig['ddnsdomainkeyalgorithm']) || ($pconfig['ddnsdomainkeyalgorithm'] == "hmac-md5")) &&
1585 67784aa6 Steve Beaver
			    (empty($pconfig['ddnsclientupdates']) || ($pconfig['ddnsclientupdates'] == "allow")) &&
1586
			    empty($pconfig['ddnsdomainkey'])) {
1587 afe62c2b Phil Davis
				$showadv = false;
1588
			} else {
1589
				$showadv = true;
1590
			}
1591
?>
1592
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1593 6e3488e9 Phil Davis
		} else {
1594 afe62c2b Phil Davis
			// It was a click, swap the state.
1595
			showadvdns = !showadvdns;
1596 6e3488e9 Phil Davis
		}
1597 afe62c2b Phil Davis
1598
		hideCheckbox('ddnsupdate', !showadvdns);
1599
		hideInput('ddnsdomain', !showadvdns);
1600 cf15bcb4 Ross Williams
		hideCheckbox('ddnsforcehostname', !showadvdns);
1601 afe62c2b Phil Davis
		hideInput('ddnsdomainprimary', !showadvdns);
1602
		hideInput('ddnsdomainkeyname', !showadvdns);
1603 534d7d69 Joeri Capens
		hideInput('ddnsdomainkeyalgorithm', !showadvdns);
1604 afe62c2b Phil Davis
		hideInput('ddnsdomainkey', !showadvdns);
1605 67784aa6 Steve Beaver
		hideInput('ddnsclientupdates', !showadvdns);
1606 afe62c2b Phil Davis
1607
		if (showadvdns) {
1608
			text = "<?=gettext('Hide Advanced');?>";
1609
		} else {
1610
			text = "<?=gettext('Display Advanced');?>";
1611
		}
1612
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1613 b5f6e690 Stephen Beaver
	}
1614
1615
	$('#btnadvdns').click(function(event) {
1616
		show_advdns();
1617
	});
1618
1619 afe62c2b Phil Davis
	// Show advanced MAC options ======================================================================================
1620 b5f6e690 Stephen Beaver
	var showadvmac = false;
1621
1622 afe62c2b Phil Davis
	function show_advmac(ispageload) {
1623
		var text;
1624
		// On page load decide the initial state based on the data.
1625
		if (ispageload) {
1626 8f8682f7 Phil Davis
<?php
1627 afe62c2b Phil Davis
			if (empty($pconfig['mac_allow']) && empty($pconfig['mac_deny'])) {
1628
				$showadv = false;
1629
			} else {
1630
				$showadv = true;
1631
			}
1632
?>
1633
			showadvmac = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1634 6e3488e9 Phil Davis
		} else {
1635 afe62c2b Phil Davis
			// It was a click, swap the state.
1636
			showadvmac = !showadvmac;
1637 6e3488e9 Phil Davis
		}
1638 b5f6e690 Stephen Beaver
1639 afe62c2b Phil Davis
		hideInput('mac_allow', !showadvmac);
1640
		hideInput('mac_deny', !showadvmac);
1641 b5f6e690 Stephen Beaver
1642 afe62c2b Phil Davis
		if (showadvmac) {
1643
			text = "<?=gettext('Hide Advanced');?>";
1644
		} else {
1645
			text = "<?=gettext('Display Advanced');?>";
1646
		}
1647
		$('#btnadvmac').html('<i class="fa fa-cog"></i> ' + text);
1648 b5f6e690 Stephen Beaver
	}
1649
1650
	$('#btnadvmac').click(function(event) {
1651 afe62c2b Phil Davis
		show_advmac();
1652 b5f6e690 Stephen Beaver
	});
1653
1654 afe62c2b Phil Davis
	// Show advanced NTP options ======================================================================================
1655 b5f6e690 Stephen Beaver
	var showadvntp = false;
1656
1657 afe62c2b Phil Davis
	function show_advntp(ispageload) {
1658
		var text;
1659
		// On page load decide the initial state based on the data.
1660
		if (ispageload) {
1661 8f8682f7 Phil Davis
<?php
1662 afe62c2b Phil Davis
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1663
				$showadv = false;
1664
			} else {
1665
				$showadv = true;
1666
			}
1667
?>
1668
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1669 6e3488e9 Phil Davis
		} else {
1670 afe62c2b Phil Davis
			// It was a click, swap the state.
1671
			showadvntp = !showadvntp;
1672 6e3488e9 Phil Davis
		}
1673 b5f6e690 Stephen Beaver
1674 afe62c2b Phil Davis
		hideInput('ntp1', !showadvntp);
1675
		hideInput('ntp2', !showadvntp);
1676 b5f6e690 Stephen Beaver
1677 afe62c2b Phil Davis
		if (showadvntp) {
1678
			text = "<?=gettext('Hide Advanced');?>";
1679
		} else {
1680
			text = "<?=gettext('Display Advanced');?>";
1681
		}
1682
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1683 b5f6e690 Stephen Beaver
	}
1684
1685
	$('#btnadvntp').click(function(event) {
1686
		show_advntp();
1687
	});
1688
1689 afe62c2b Phil Davis
	// Show advanced TFTP options ======================================================================================
1690
	var showadvtftp = false;
1691 b5f6e690 Stephen Beaver
1692 afe62c2b Phil Davis
	function show_advtftp(ispageload) {
1693
		var text;
1694
		// On page load decide the initial state based on the data.
1695
		if (ispageload) {
1696 8f8682f7 Phil Davis
<?php
1697 afe62c2b Phil Davis
			if (empty($pconfig['tftp'])) {
1698
				$showadv = false;
1699
			} else {
1700
				$showadv = true;
1701
			}
1702
?>
1703
			showadvtftp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1704 6e3488e9 Phil Davis
		} else {
1705 afe62c2b Phil Davis
			// It was a click, swap the state.
1706
			showadvtftp = !showadvtftp;
1707 6e3488e9 Phil Davis
		}
1708 b5f6e690 Stephen Beaver
1709 afe62c2b Phil Davis
		hideInput('tftp', !showadvtftp);
1710 b5f6e690 Stephen Beaver
1711 afe62c2b Phil Davis
		if (showadvtftp) {
1712
			text = "<?=gettext('Hide Advanced');?>";
1713
		} else {
1714
			text = "<?=gettext('Display Advanced');?>";
1715
		}
1716
		$('#btnadvtftp').html('<i class="fa fa-cog"></i> ' + text);
1717 b5f6e690 Stephen Beaver
	}
1718
1719
	$('#btnadvtftp').click(function(event) {
1720
		show_advtftp();
1721
	});
1722
1723 afe62c2b Phil Davis
	// Show advanced LDAP options ======================================================================================
1724 b5f6e690 Stephen Beaver
	var showadvldap = false;
1725
1726 afe62c2b Phil Davis
	function show_advldap(ispageload) {
1727
		var text;
1728
		// On page load decide the initial state based on the data.
1729
		if (ispageload) {
1730 8f8682f7 Phil Davis
<?php
1731 afe62c2b Phil Davis
			if (empty($pconfig['ldap'])) {
1732
				$showadv = false;
1733
			} else {
1734
				$showadv = true;
1735
			}
1736
?>
1737
			showadvldap = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1738 6e3488e9 Phil Davis
		} else {
1739 afe62c2b Phil Davis
			// It was a click, swap the state.
1740
			showadvldap = !showadvldap;
1741 6e3488e9 Phil Davis
		}
1742 b5f6e690 Stephen Beaver
1743 afe62c2b Phil Davis
		hideInput('ldap', !showadvldap);
1744 b5f6e690 Stephen Beaver
1745 afe62c2b Phil Davis
		if (showadvldap) {
1746
			text = "<?=gettext('Hide Advanced');?>";
1747
		} else {
1748
			text = "<?=gettext('Display Advanced');?>";
1749
		}
1750
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1751 b5f6e690 Stephen Beaver
	}
1752
1753
	$('#btnadvldap').click(function(event) {
1754
		show_advldap();
1755
	});
1756
1757 eef93144 Jared Dillard
	// Show advanced additional opts options ===========================================================================
1758 b5f6e690 Stephen Beaver
	var showadvopts = false;
1759
1760 afe62c2b Phil Davis
	function show_advopts(ispageload) {
1761
		var text;
1762
		// On page load decide the initial state based on the data.
1763
		if (ispageload) {
1764 8f8682f7 Phil Davis
<?php
1765 afe62c2b Phil Davis
			if (empty($pconfig['numberoptions']) ||
1766
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1767
				$showadv = false;
1768
			} else {
1769
				$showadv = true;
1770
			}
1771
?>
1772
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1773 6e3488e9 Phil Davis
		} else {
1774 afe62c2b Phil Davis
			// It was a click, swap the state.
1775
			showadvopts = !showadvopts;
1776 6e3488e9 Phil Davis
		}
1777 b5f6e690 Stephen Beaver
1778 afe62c2b Phil Davis
		hideClass('adnlopts', !showadvopts);
1779 b5f6e690 Stephen Beaver
1780 afe62c2b Phil Davis
		if (showadvopts) {
1781
			text = "<?=gettext('Hide Advanced');?>";
1782
		} else {
1783
			text = "<?=gettext('Display Advanced');?>";
1784
		}
1785
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1786 b5f6e690 Stephen Beaver
	}
1787
1788
	$('#btnadvopts').click(function(event) {
1789
		show_advopts();
1790
	});
1791
1792 68de2169 Phil Davis
	// Show advanced Network Booting options ===========================================================================
1793
	var showadvnwkboot = false;
1794
1795
	function show_advnwkboot(ispageload) {
1796
		var text;
1797
		// On page load decide the initial state based on the data.
1798
		if (ispageload) {
1799
<?php
1800
			if (empty($pconfig['netboot'])) {
1801
				$showadv = false;
1802
			} else {
1803
				$showadv = true;
1804
			}
1805
?>
1806
			showadvnwkboot = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1807
		} else {
1808
			// It was a click, swap the state.
1809
			showadvnwkboot = !showadvnwkboot;
1810
		}
1811
1812
		hideCheckbox('netboot', !showadvnwkboot);
1813
		hideInput('nextserver', !showadvnwkboot);
1814
		hideInput('filename', !showadvnwkboot);
1815
		hideInput('filename32', !showadvnwkboot);
1816
		hideInput('filename64', !showadvnwkboot);
1817
		hideInput('rootpath', !showadvnwkboot);
1818
1819
		if (showadvnwkboot) {
1820
			text = "<?=gettext('Hide Advanced');?>";
1821
		} else {
1822
			text = "<?=gettext('Display Advanced');?>";
1823
		}
1824
		$('#btnadvnwkboot').html('<i class="fa fa-cog"></i> ' + text);
1825
	}
1826
1827
	$('#btnadvnwkboot').click(function(event) {
1828
		show_advnwkboot();
1829
	});
1830
1831 eef93144 Jared Dillard
	// ---------- On initial page load ------------------------------------------------------------
1832
1833 afe62c2b Phil Davis
	show_advdns(true);
1834
	show_advmac(true);
1835
	show_advntp(true);
1836
	show_advtftp(true);
1837
	show_advldap(true);
1838
	show_advopts(true);
1839 68de2169 Phil Davis
	show_advnwkboot(true);
1840 0bc61baa Stephen Beaver
1841
	// Suppress "Delete row" button if there are fewer than two rows
1842
	checkLastRow();
1843 b5f6e690 Stephen Beaver
});
1844 180db186 Colin Fleming
//]]>
1845 5b237745 Scott Ullrich
</script>
1846 b5f6e690 Stephen Beaver
1847 3c9befb9 Chris Buechler
<?php include("foot.inc");