Project

General

Profile

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