Project

General

Profile

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