Project

General

Profile

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