Project

General

Profile

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