Project

General

Profile

Download (50.3 KB) Statistics
| Branch: | Tag: | Revision:
1 e9f147c8 Scott Ullrich
<?php
2 5b237745 Scott Ullrich
/*
3 c5d81585 Renato Botelho
 * services_dhcp.php
4 919d91f9 Phil Davis
 *
5 c5d81585 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 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
		unset($a_maps[$_GET['id']]);
636
		write_config();
637 8f8682f7 Phil Davis
		if (isset($config['dhcpd'][$if]['enable'])) {
638 a368a026 Ermal Lu?i
			mark_subsystem_dirty('staticmaps');
639 8f8682f7 Phil Davis
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic'])) {
640 a368a026 Ermal Lu?i
				mark_subsystem_dirty('hosts');
641 8f8682f7 Phil Davis
			}
642 6a01ea44 Bill Marquette
		}
643 b5f6e690 Stephen Beaver
644 5b237745 Scott Ullrich
		header("Location: services_dhcp.php?if={$if}");
645
		exit;
646
	}
647
}
648 4df96eff Scott Ullrich
649 3c9befb9 Chris Buechler
// Build an HTML table that can be inserted into a Form_StaticText element
650 b5f6e690 Stephen Beaver
function build_pooltable() {
651 96ab6943 Chris Buechler
	global $a_pools, $if;
652 b5f6e690 Stephen Beaver
653
	$pooltbl =	'<div class="table-responsive">';
654
	$pooltbl .=		'<table class="table table-striped table-hover table-condensed">';
655
	$pooltbl .=			'<thead>';
656
	$pooltbl .=				'<tr>';
657
	$pooltbl .=					'<th>' . gettext("Pool Start") . '</th>';
658
	$pooltbl .=					'<th>' . gettext("Pool End") . '</th>';
659
	$pooltbl .=					'<th>' . gettext("Description") . '</th>';
660 d7d7820e Phil Davis
	$pooltbl .=					'<th>' . gettext("Actions") . '</th>';
661 b5f6e690 Stephen Beaver
	$pooltbl .=				'</tr>';
662
	$pooltbl .=			'</thead>';
663
	$pooltbl .=			'<tbody>';
664
665
	if (is_array($a_pools)) {
666
		$i = 0;
667
		foreach ($a_pools as $poolent) {
668
			if (!empty($poolent['range']['from']) && !empty($poolent['range']['to'])) {
669
				$pooltbl .= '<tr>';
670
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
671
							htmlspecialchars($poolent['range']['from']) . '</td>';
672
673
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
674
							htmlspecialchars($poolent['range']['to']) . '</td>';
675
676
				$pooltbl .= '<td ondblclick="document.location=\'services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '\';">' .
677
							htmlspecialchars($poolent['descr']) . '</td>';
678
679 d7d7820e Phil Davis
				$pooltbl .= '<td><a class="fa fa-pencil" title="'. gettext("Edit pool") . '" href="services_dhcp.php?if=' . htmlspecialchars($if) . '&pool=' . $i . '"></a>';
680 b5f6e690 Stephen Beaver
681 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>';
682 b5f6e690 Stephen Beaver
				$pooltbl .= '</tr>';
683
			}
684
		$i++;
685
		}
686
	}
687
688
	$pooltbl .=			'</tbody>';
689
	$pooltbl .=		'</table>';
690
	$pooltbl .= '</div>';
691
692
	return($pooltbl);
693
}
694
695 bf27317d Phil Davis
$pgtitle = array(gettext("Services"), gettext("DHCP Server"));
696 fa94122b k-paulius
697
if (!empty($if) && !isset($config['dhcrelay']['enable']) && isset($iflist[$if])) {
698
	$pgtitle[] = $iflist[$if];
699
}
700 b32dd0a6 jim-p
$shortcut_section = "dhcp";
701 5224b8e7 jim-p
702 4df96eff Scott Ullrich
include("head.inc");
703
704 6e3488e9 Phil Davis
if ($input_errors) {
705 b5f6e690 Stephen Beaver
	print_input_errors($input_errors);
706 6e3488e9 Phil Davis
}
707 4df96eff Scott Ullrich
708 6e3488e9 Phil Davis
if ($savemsg) {
709 b5f6e690 Stephen Beaver
	print_info_box($savemsg, 'success');
710 6e3488e9 Phil Davis
}
711 678dfd0f Erik Fonnesbeck
712 b5f6e690 Stephen Beaver
if (isset($config['dhcrelay']['enable'])) {
713
	print_info_box(gettext("DHCP Relay is currently enabled. Cannot enable the DHCP Server service while the DHCP Relay is enabled on any interface."));
714
	include("foot.inc");
715
	exit;
716
}
717 4e9cd828 Seth Mos
718 6e3488e9 Phil Davis
if (is_subsystem_dirty('staticmaps')) {
719 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."));
720 6e3488e9 Phil Davis
}
721 b5f6e690 Stephen Beaver
722
/* active tabs */
723
$tab_array = array();
724
$tabscounter = 0;
725
$i = 0;
726 8a73f407 Stephen Beaver
727 b5f6e690 Stephen Beaver
foreach ($iflist as $ifent => $ifname) {
728
	$oc = $config['interfaces'][$ifent];
729
	if ((is_array($config['dhcpd'][$ifent]) && !isset($config['dhcpd'][$ifent]['enable']) && (!is_ipaddrv4($oc['ipaddr']))) ||
730 6e3488e9 Phil Davis
	    (!is_array($config['dhcpd'][$ifent]) && (!is_ipaddrv4($oc['ipaddr'])))) {
731 b5f6e690 Stephen Beaver
		continue;
732 518030b3 Scott Ullrich
	}
733 4e9cd828 Seth Mos
734 b5f6e690 Stephen Beaver
	if ($ifent == $if) {
735
		$active = true;
736
	} else {
737
		$active = false;
738 b1d132f5 Scott Ullrich
	}
739
740 b5f6e690 Stephen Beaver
	$tab_array[] = array($ifname, $active, "services_dhcp.php?if={$ifent}");
741
	$tabscounter++;
742
}
743 ad171999 Seth Mos
744 b5f6e690 Stephen Beaver
if ($tabscounter == 0) {
745
	print_info_box(gettext("The DHCP Server can only be enabled on interfaces configured with a static IPv4 address. This system has none."));
746
	include("foot.inc");
747
	exit;
748
}
749 1f1a08c8 jim-p
750 b5f6e690 Stephen Beaver
display_top_tabs($tab_array);
751
752 8f58b51b jim-p
$form = new Form();
753 b5f6e690 Stephen Beaver
754
$section = new Form_Section('General Options');
755
756
if (!is_numeric($pool) && !($act == "newpool")) {
757
	$section->addInput(new Form_Checkbox(
758
		'enable',
759
		'Enable',
760
		sprintf(gettext("Enable DHCP server on %s interface"), htmlspecialchars($iflist[$if])),
761
		$pconfig['enable']
762
	));
763
} else {
764 02342d8c k-paulius
	print_info_box(gettext('Editing pool-specific options. To return to the Interface, click its tab above.'), 'info', false);
765 b5f6e690 Stephen Beaver
}
766 6c23757b Martin Fuchs
767 6d53301b Jose Luis Duran
$section->addInput(new Form_Checkbox(
768
	'ignorebootp',
769
	'BOOTP',
770
	'Ignore BOOTP queries',
771
	$pconfig['ignorebootp']
772
));
773
774 b5f6e690 Stephen Beaver
$section->addInput(new Form_Checkbox(
775
	'denyunknown',
776
	'Deny unknown clients',
777
	'Only the clients defined below will get DHCP leases from this server.',
778
	$pconfig['denyunknown']
779
));
780
781 3475eb04 Andrew Pilloud
$section->addInput(new Form_Checkbox(
782
	'nonak',
783
	'Ignore denied clients',
784
	'Denied clients will be ignored rather than rejected.',
785
	$pconfig['nonak']
786 8209517d jim-p
))->setHelp("This option is not compatible with failover and cannot be enabled when a Failover Peer IP address is configured.");
787 3475eb04 Andrew Pilloud
788
789 b5f6e690 Stephen Beaver
if (is_numeric($pool) || ($act == "newpool")) {
790
	$section->addInput(new Form_Input(
791
		'descr',
792
		'Pool Description',
793
		'text',
794
		$pconfig['descr']
795
	));
796
}
797 6c23757b Martin Fuchs
798 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
799
	'Subnet',
800
	gen_subnet($ifcfgip, $ifcfgsn)
801
));
802 4e9cd828 Seth Mos
803 b5f6e690 Stephen Beaver
$section->addInput(new Form_StaticText(
804
	'Subnet mask',
805
	gen_subnet_mask($ifcfgsn)
806
));
807 5b237745 Scott Ullrich
808 8a73f407 Stephen Beaver
// Compose a string to display the required address ranges
809 b90d635e Renato Botelho
$rangestr = ip_after($subnet_start) . ' - ' . ip_before($subnet_end);
810 b5f6e690 Stephen Beaver
811
if (is_numeric($pool) || ($act == "newpool")) {
812 4bb7c0d1 bruno
	$rangestr .= '<br />' . gettext('In-use DHCP Pool Ranges:');
813 b5f6e690 Stephen Beaver
	if (is_array($config['dhcpd'][$if]['range'])) {
814
		$rangestr .= '<br />' . $config['dhcpd'][$if]['range']['from'] . ' - ' . $config['dhcpd'][$if]['range']['to'];
815 3d7b7757 Chris Buechler
	}
816 b5f6e690 Stephen Beaver
817
	foreach ($a_pools as $p) {
818
		if (is_array($p['range'])) {
819
			$rangestr .= '<br />' . $p['range']['from'] . ' - ' . $p['range']['to'];
820 8f8682f7 Phil Davis
		}
821 934240ef Ermal Luçi
	}
822 b5f6e690 Stephen Beaver
}
823
824
$section->addInput(new Form_StaticText(
825
	'Available range',
826
	$rangestr
827
));
828
829
if ($is_olsr_enabled) {
830
	$section->addInput(new Form_Select(
831
		'netmask',
832
		'Subnet mask',
833
		$pconfig['netmask'],
834
		array_combine(range(32, 1, -1), range(32, 1, -1))
835
	));
836
}
837
838
$group = new Form_Group('Range');
839
840
$group->add(new Form_IpAddress(
841
	'range_from',
842
	null,
843
	$pconfig['range_from']
844
))->setHelp('From');
845
846
$group->add(new Form_IpAddress(
847
	'range_to',
848
	null,
849
	$pconfig['range_to']
850
))->setHelp('To');
851
852
$section->add($group);
853
854
$form->add($section);
855
856
if (!is_numeric($pool) && !($act == "newpool")) {
857 5f88f964 k-paulius
	$section = new Form_Section('Additional Pools');
858 b5f6e690 Stephen Beaver
859
	$btnaddpool = new Form_Button(
860
		'btnaddpool',
861 faab522f Renato Botelho
		'Add pool',
862 37676f4e jim-p
		'services_dhcp.php?if=' . htmlspecialchars($if) . '&act=newpool',
863
		'fa-plus'
864 b5f6e690 Stephen Beaver
	);
865 37676f4e jim-p
	$btnaddpool->addClass('btn-success');
866 b5f6e690 Stephen Beaver
867
	$section->addInput(new Form_StaticText(
868
		'Add',
869
		$btnaddpool
870 e78ecb96 NOYB
	))->setHelp('If additional pools of addresses are needed inside of this subnet outside the above Range, they may be specified here.');
871 b5f6e690 Stephen Beaver
872
	if (is_array($a_pools)) {
873
		$section->addInput(new Form_StaticText(
874
			null,
875
			build_pooltable()
876
		));
877 f0cdf141 Scott Ullrich
	}
878 b5f6e690 Stephen Beaver
879
	$form->add($section);
880
}
881
882
$section = new Form_Section('Servers');
883
884
$section->addInput(new Form_IpAddress(
885
	'wins1',
886
	'WINS servers',
887
	$pconfig['wins1']
888
))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'WINS Server 1');
889
890
$section->addInput(new Form_IpAddress(
891
	'wins2',
892
	null,
893
	$pconfig['wins2']
894
))->setPattern('[.a-zA-Z0-9_]+')->setAttribute('placeholder', 'WINS Server 2');
895
896 6e3488e9 Phil Davis
for ($idx=1; $idx<=4; $idx++) {
897 b5f6e690 Stephen Beaver
	$section->addInput(new Form_IpAddress(
898
		'dns' . $idx,
899
		($idx == 1) ? 'DNS servers':null,
900
		$pconfig['dns' . $idx]
901 f7c12c94 NOYB
	))->setPattern('[.a-zA-Z0-9_]+')->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.':'');
902 b5f6e690 Stephen Beaver
}
903
904
$form->add($section);
905
906 5f88f964 k-paulius
$section = new Form_Section('Other Options');
907 b5f6e690 Stephen Beaver
908
$section->addInput(new Form_IpAddress(
909
	'gateway',
910
	'Gateway',
911
	$pconfig['gateway']
912
))->setPattern('[.a-zA-Z0-9_]+')
913 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.');
914 b5f6e690 Stephen Beaver
915
$section->addInput(new Form_Input(
916
	'domain',
917
	'Domain name',
918
	'text',
919
	$pconfig['domain']
920 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.');
921 b5f6e690 Stephen Beaver
922
$section->addInput(new Form_Input(
923
	'domainsearchlist',
924
	'Domain search list',
925
	'text',
926
	$pconfig['domainsearchlist']
927 e78ecb96 NOYB
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
928 b5f6e690 Stephen Beaver
929
$section->addInput(new Form_Input(
930
	'deftime',
931
	'Default lease time',
932
	'number',
933
	$pconfig['deftime']
934 e78ecb96 NOYB
))->setHelp('This is used for clients that do not ask for a specific expiration time. The default is 7200 seconds.');
935 b5f6e690 Stephen Beaver
936
$section->addInput(new Form_Input(
937
	'maxtime',
938
	'Maximum lease time',
939
	'number',
940
	$pconfig['maxtime']
941 e78ecb96 NOYB
))->setHelp('This is the maximum lease time for clients that ask for a specific expiration time. The default is 86400 seconds.');
942 b5f6e690 Stephen Beaver
943
if (!is_numeric($pool) && !($act == "newpool")) {
944
	$section->addInput(new Form_IpAddress(
945
		'failover_peerip',
946
		'Failover peer IP',
947
		$pconfig['failover_peerip']
948 af8f79b1 Chris Buechler
	))->setHelp('Leave blank to disable. Enter the interface IP address of the other machine. Machines must be using CARP. ' .
949 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).');
950 b5f6e690 Stephen Beaver
}
951
952
if (!is_numeric($pool) && !($act == "newpool")) {
953
	$section->addInput(new Form_Checkbox(
954
		'staticarp',
955
		'Static ARP',
956
		'Enable Static ARP entries',
957
		$pconfig['staticarp']
958 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.');
959 b5f6e690 Stephen Beaver
960
	$section->addInput(new Form_Checkbox(
961
		'dhcpleaseinlocaltime',
962
		'Time format change',
963
		'Change DHCP display lease time from UTC to local time',
964
		$pconfig['dhcpleaseinlocaltime']
965
	))->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.' .
966 e78ecb96 NOYB
				' This will be used for all DHCP interfaces lease time.');
967 18d316a5 heper
	$section->addInput(new Form_Checkbox(
968
		'statsgraph',
969 61237194 Chris Buechler
		'Statistics graphs',
970
		'Enable RRD statistics graphs',
971 18d316a5 heper
		$pconfig['statsgraph']
972 61237194 Chris Buechler
	))->setHelp('Enable this to add DHCP leases statistics to the RRD graphs. Disabled by default.');
973 b5f6e690 Stephen Beaver
}
974
975
// DDNS
976
$btnadv = new Form_Button(
977
	'btnadvdns',
978 afe62c2b Phil Davis
	'Display Advanced',
979 3314e626 jim-p
	null,
980
	'fa-cog'
981 b5f6e690 Stephen Beaver
);
982
983 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
984 b5f6e690 Stephen Beaver
985
$section->addInput(new Form_StaticText(
986
	'Dynamic DNS',
987
	$btnadv
988
));
989
990
$section->addInput(new Form_Checkbox(
991
	'ddnsupdate',
992
	null,
993
	'Enable registration of DHCP client names in DNS',
994
	$pconfig['ddnsupdate']
995
));
996
997
$section->addInput(new Form_Input(
998
	'ddnsdomain',
999
	'DDNS Domain',
1000 e8da0bcd Jeremy Porter
	'text',
1001 b5f6e690 Stephen Beaver
	$pconfig['ddnsdomain']
1002
))->setHelp('Leave blank to disable dynamic DNS registration.' . '<br />' .
1003
			'Enter the dynamic DNS domain which will be used to register client names in the DNS server.');
1004
1005
$section->addInput(new Form_IpAddress(
1006
	'ddnsdomainprimary',
1007
	'Primary DDNS address',
1008
	$pconfig['ddnsdomainprimary']
1009 cb6c20a9 NewEraCracker
))->setHelp('Primary domain name server IP address for the dynamic domain name.');
1010 b5f6e690 Stephen Beaver
1011
$section->addInput(new Form_Input(
1012
	'ddnsdomainkeyname',
1013
	'DNS Domain key',
1014
	'text',
1015
	$pconfig['ddnsdomainkeyname']
1016 cb6c20a9 NewEraCracker
))->setHelp('Dynamic DNS domain key name which will be used to register client names in the DNS server.');
1017 b5f6e690 Stephen Beaver
1018
$section->addInput(new Form_Input(
1019
	'ddnsdomainkey',
1020
	'DNS Domain key secret',
1021
	'text',
1022
	$pconfig['ddnsdomainkey']
1023 4d55ef96 Chris Buechler
))->setHelp('Dynamic DNS domain key secret (HMAC-MD5) which will be used to register client names in the DNS server.');
1024 b5f6e690 Stephen Beaver
1025
// Advanced MAC
1026
$btnadv = new Form_Button(
1027
	'btnadvmac',
1028 afe62c2b Phil Davis
	'Display Advanced',
1029 3314e626 jim-p
	null,
1030
	'fa-cog'
1031 b5f6e690 Stephen Beaver
);
1032
1033 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1034 b5f6e690 Stephen Beaver
1035
$section->addInput(new Form_StaticText(
1036
	'MAC address control',
1037
	$btnadv
1038
));
1039
1040
$section->addInput(new Form_Input(
1041
	'mac_allow',
1042 ef2936e6 Stephen Beaver
	'MAC Allow',
1043 b5f6e690 Stephen Beaver
	'text',
1044
	$pconfig['mac_allow']
1045
))->setHelp('List of partial MAC addresses to allow, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1046
1047
$section->addInput(new Form_Input(
1048
	'mac_deny',
1049 ef2936e6 Stephen Beaver
	'MAC Deny',
1050 b5f6e690 Stephen Beaver
	'text',
1051
	$pconfig['mac_deny']
1052
))->setHelp('List of partial MAC addresses to deny access, comma separated, no spaces, e.g.: 00:00:00,01:E5:FF');
1053
1054
// Advanced NTP
1055
$btnadv = new Form_Button(
1056
	'btnadvntp',
1057 afe62c2b Phil Davis
	'Display Advanced',
1058 3314e626 jim-p
	null,
1059
	'fa-cog'
1060 b5f6e690 Stephen Beaver
);
1061
1062 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1063 b5f6e690 Stephen Beaver
1064
$section->addInput(new Form_StaticText(
1065 ff3da1e7 Stephen Beaver
	'NTP',
1066 b5f6e690 Stephen Beaver
	$btnadv
1067
));
1068
1069
$section->addInput(new Form_IpAddress(
1070
	'ntp1',
1071 ff3da1e7 Stephen Beaver
	'NTP Server 1',
1072 b5f6e690 Stephen Beaver
	$pconfig['ntp1']
1073 39bfb267 Chris Buechler
))->setPattern('[.a-zA-Z0-9_]+');
1074 b5f6e690 Stephen Beaver
1075
$section->addInput(new Form_IpAddress(
1076
	'ntp2',
1077 ff3da1e7 Stephen Beaver
	'NTP Server 2',
1078 b5f6e690 Stephen Beaver
	$pconfig['ntp2']
1079 39bfb267 Chris Buechler
))->setPattern('[.a-zA-Z0-9_]+');
1080 b5f6e690 Stephen Beaver
1081
// Advanced TFTP
1082
$btnadv = new Form_Button(
1083
	'btnadvtftp',
1084 afe62c2b Phil Davis
	'Display Advanced',
1085 3314e626 jim-p
	null,
1086
	'fa-cog'
1087 b5f6e690 Stephen Beaver
);
1088
1089 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1090 b5f6e690 Stephen Beaver
1091
$section->addInput(new Form_StaticText(
1092 ff3da1e7 Stephen Beaver
	'TFTP',
1093 b5f6e690 Stephen Beaver
	$btnadv
1094
));
1095
1096 c411661a doktornotor
$section->addInput(new Form_Input(
1097 b5f6e690 Stephen Beaver
	'tftp',
1098 ff3da1e7 Stephen Beaver
	'TFTP Server',
1099 b5f6e690 Stephen Beaver
	$pconfig['tftp']
1100 c411661a doktornotor
))->setHelp('Leave blank to disable. Enter a valid IP address, hostname or URL for the TFTP server.');
1101 b5f6e690 Stephen Beaver
1102
// Advanced LDAP
1103
$btnadv = new Form_Button(
1104
	'btnadvldap',
1105 afe62c2b Phil Davis
	'Display Advanced',
1106 3314e626 jim-p
	null,
1107
	'fa-cog'
1108 b5f6e690 Stephen Beaver
);
1109
1110 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1111 b5f6e690 Stephen Beaver
1112
$section->addInput(new Form_StaticText(
1113 ff3da1e7 Stephen Beaver
	'LDAP',
1114 b5f6e690 Stephen Beaver
	$btnadv
1115
));
1116
1117
$section->addInput(new Form_Input(
1118
	'ldap',
1119 ff3da1e7 Stephen Beaver
	'LDAP Server URI',
1120 b5f6e690 Stephen Beaver
	'text',
1121
	$pconfig['ldap']
1122
))->setHelp('Leave blank to disable. Enter a full URI for the LDAP server in the form ldap://ldap.example.com/dc=example,dc=com ');
1123
1124 68de2169 Phil Davis
// Advanced Network Booting options
1125
$btnadv = new Form_Button(
1126
	'btnadvnwkboot',
1127
	'Display Advanced',
1128
	null,
1129
	'fa-cog'
1130
);
1131
1132
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1133
1134
$section->addInput(new Form_StaticText(
1135
	'Network Booting',
1136
	$btnadv
1137
));
1138
1139
$section->addInput(new Form_Checkbox(
1140
	'netboot',
1141
	'Enable',
1142
	'Enables network booting',
1143
	$pconfig['netboot']
1144
));
1145
1146
$section->addInput(new Form_IpAddress(
1147
	'nextserver',
1148
	'Next Server',
1149
	$pconfig['nextserver']
1150
))->setHelp('Enter the IP address of the next server');
1151
1152
$section->addInput(new Form_Input(
1153
	'filename',
1154
	'Default BIOS file name',
1155
	'text',
1156
	$pconfig['filename']
1157
));
1158
1159
$section->addInput(new Form_Input(
1160
	'filename32',
1161
	'UEFI 32 bit file name',
1162
	'text',
1163
	$pconfig['filename32']
1164
));
1165
1166
$section->addInput(new Form_Input(
1167
	'filename64',
1168
	'UEFI 64 bit file name',
1169
	'text',
1170
	$pconfig['filename64']
1171
))->setHelp('Both a filename and a boot server must be configured for this to work! ' .
1172
			'All three filenames and a configured boot server are necessary for UEFI to work! ');
1173
1174
$section->addInput(new Form_Input(
1175
	'rootpath',
1176
	'Root path',
1177
	'text',
1178
	$pconfig['rootpath']
1179
))->setHelp('string-format: iscsi:(servername):(protocol):(port):(LUN):targetname ');
1180
1181 b5f6e690 Stephen Beaver
// Advanced Additional options
1182
$btnadv = new Form_Button(
1183
	'btnadvopts',
1184 afe62c2b Phil Davis
	'Display Advanced',
1185 3314e626 jim-p
	null,
1186
	'fa-cog'
1187 b5f6e690 Stephen Beaver
);
1188
1189 347c0214 Phil Davis
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
1190 b5f6e690 Stephen Beaver
1191
$section->addInput(new Form_StaticText(
1192
	'Additional BOOTP/DHCP Options',
1193
	$btnadv
1194
));
1195
1196 f8088b00 Phil Davis
$form->add($section);
1197
1198 b5f6e690 Stephen Beaver
$section = new Form_Section('Additional BOOTP/DHCP Options');
1199
$section->addClass('adnlopts');
1200
1201
$section->addInput(new Form_StaticText(
1202
	null,
1203 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.') . ' ' .
1204 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>')
1205 b5f6e690 Stephen Beaver
));
1206
1207 6e3488e9 Phil Davis
if (!$pconfig['numberoptions']) {
1208 b5f6e690 Stephen Beaver
	$pconfig['numberoptions']['item']  = array(array('number' => '', 'type' => 'text', 'value' => ''));
1209
}
1210
1211
$customitemtypes = array(
1212
	'text' => gettext('Text'), 'string' => gettext('String'), 'boolean' => gettext('Boolean'),
1213
	'unsigned integer 8' => gettext('Unsigned 8-bit integer'), 'unsigned integer 16' => gettext('Unsigned 16-bit integer'), 'unsigned integer 32' => gettext('Unsigned 32-bit integer'),
1214
	'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')
1215
);
1216
1217
$numrows = count($item) -1;
1218
$counter = 0;
1219
1220
$numrows = count($pconfig['numberoptions']['item']) -1;
1221
1222
foreach ($pconfig['numberoptions']['item'] as $item) {
1223
	$number = $item['number'];
1224
	$itemtype = $item['type'];
1225 65cce9d7 Renato Botelho
	$value = base64_decode($item['value']);
1226 b5f6e690 Stephen Beaver
1227
	$group = new Form_Group(($counter == 0) ? 'Option':null);
1228
	$group->addClass('repeatable');
1229
1230
	$group->add(new Form_Input(
1231
		'number' . $counter,
1232
		null,
1233
		'text',
1234
		$number
1235
	))->setHelp($numrows == $counter ? 'Number':null);
1236
1237
1238
	$group->add(new Form_Select(
1239
		'itemtype' . $counter,
1240
		null,
1241
		$itemtype,
1242
		$customitemtypes
1243 8a73f407 Stephen Beaver
	))->setWidth(3)->setHelp($numrows == $counter ? 'Type':null);
1244 b5f6e690 Stephen Beaver
1245
	$group->add(new Form_Input(
1246
		'value' . $counter,
1247
		null,
1248
		'text',
1249
		$value
1250
	))->setHelp($numrows == $counter ? 'Value':null);
1251
1252
	$group->add(new Form_Button(
1253
		'deleterow' . $counter,
1254 faab522f Renato Botelho
		'Delete',
1255 cd7ddae6 jim-p
		null,
1256
		'fa-trash'
1257
	))->addClass('btn-warning');
1258 b5f6e690 Stephen Beaver
1259
	$section->add($group);
1260
1261
	$counter++;
1262
}
1263
1264
$section->addInput(new Form_Button(
1265
	'addrow',
1266 faab522f Renato Botelho
	'Add',
1267 cd7ddae6 jim-p
	null,
1268
	'fa-plus'
1269
))->addClass('btn-success');
1270 b5f6e690 Stephen Beaver
1271
$form->add($section);
1272
1273
if ($act == "newpool") {
1274
	$form->addGlobal(new Form_Input(
1275
		'act',
1276
		null,
1277
		'hidden',
1278
		'newpool'
1279
	));
1280
}
1281
1282
if (is_numeric($pool)) {
1283
	$form->addGlobal(new Form_Input(
1284
		'pool',
1285
		null,
1286
		'hidden',
1287
		$pool
1288
	));
1289
}
1290
1291
$form->addGlobal(new Form_Input(
1292
	'if',
1293
	null,
1294
	'hidden',
1295
	$if
1296
));
1297
1298
print($form);
1299
1300
// DHCP Static Mappings table
1301
1302
if (!is_numeric($pool) && !($act == "newpool")) {
1303 de792e62 jim-p
?>
1304 b5f6e690 Stephen Beaver
1305
<div class="panel panel-default">
1306 3d7a8696 k-paulius
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCP Static Mappings for this Interface")?></h2></div>
1307 b5f6e690 Stephen Beaver
	<div class="table-responsive">
1308 55f67b5a Stephen Beaver
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
1309 b5f6e690 Stephen Beaver
				<thead>
1310
					<tr>
1311
						<th><?=gettext("Static ARP")?></th>
1312
						<th><?=gettext("MAC address")?></th>
1313
						<th><?=gettext("IP address")?></th>
1314
						<th><?=gettext("Hostname")?></th>
1315
						<th><?=gettext("Description")?></th>
1316
						<th></th>
1317
					</tr>
1318
				</thead>
1319 8f8682f7 Phil Davis
<?php
1320 b5f6e690 Stephen Beaver
	if (is_array($a_maps)) {
1321
		$i = 0;
1322 8f8682f7 Phil Davis
?>
1323 b5f6e690 Stephen Beaver
				<tbody>
1324 8f8682f7 Phil Davis
<?php
1325 b5f6e690 Stephen Beaver
		foreach ($a_maps as $mapent) {
1326 8f8682f7 Phil Davis
?>
1327 b5f6e690 Stephen Beaver
					<tr>
1328 1d932e0c NOYB
						<td class="text-center" ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1329 b5f6e690 Stephen Beaver
							<?php if (isset($mapent['arp_table_static_entry'])): ?>
1330 1b7379f9 Jared Dillard
								<i class="fa fa-check"></i>
1331 b5f6e690 Stephen Beaver
							<?php endif; ?>
1332
						</td>
1333
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1334
							<?=htmlspecialchars($mapent['mac'])?>
1335
						</td>
1336
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1337
							<?=htmlspecialchars($mapent['ipaddr'])?>
1338
						</td>
1339
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1340
							<?=htmlspecialchars($mapent['hostname'])?>
1341
						</td>
1342
						<td ondblclick="document.location='services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>';">
1343
							<?=htmlspecialchars($mapent['descr'])?>
1344
						</td>
1345
						<td>
1346 9a6a8329 heper
							<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>"	href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>&amp;id=<?=$i?>"></a>
1347 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>
1348 b5f6e690 Stephen Beaver
						</td>
1349
					</tr>
1350 8f8682f7 Phil Davis
<?php
1351 b5f6e690 Stephen Beaver
		$i++;
1352
		}
1353 8f8682f7 Phil Davis
?>
1354 b5f6e690 Stephen Beaver
				</tbody>
1355 8f8682f7 Phil Davis
<?php
1356 b5f6e690 Stephen Beaver
	}
1357 8f8682f7 Phil Davis
?>
1358 82f54a42 Colin Fleming
		</table>
1359 b5f6e690 Stephen Beaver
	</div>
1360
</div>
1361 c9679d8c Stephen Beaver
1362 c10cb196 Stephen Beaver
<nav class="action-buttons">
1363 c9679d8c Stephen Beaver
	<a href="services_dhcp_edit.php?if=<?=htmlspecialchars($if)?>" class="btn btn-sm btn-success">
1364 9d5a20cf heper
		<i class="fa fa-plus icon-embed-btn"></i>
1365 c9679d8c Stephen Beaver
		<?=gettext("Add")?>
1366
	</a>
1367
</nav>
1368 8f8682f7 Phil Davis
<?php
1369 b5f6e690 Stephen Beaver
}
1370 8f8682f7 Phil Davis
?>
1371
1372 8fd9052f Colin Fleming
<script type="text/javascript">
1373 b5f6e690 Stephen Beaver
//<![CDATA[
1374 6e3488e9 Phil Davis
events.push(function() {
1375 b5f6e690 Stephen Beaver
1376
	// Show advanced DNS options ======================================================================================
1377
	var showadvdns = false;
1378
1379 afe62c2b Phil Davis
	function show_advdns(ispageload) {
1380
		var text;
1381
		// On page load decide the initial state based on the data.
1382
		if (ispageload) {
1383 b5f6e690 Stephen Beaver
<?php
1384 afe62c2b Phil Davis
			if (!$pconfig['ddnsupdate'] && empty($pconfig['ddnsdomain']) && empty($pconfig['ddnsdomainprimary']) &&
1385
			    empty($pconfig['ddnsdomainkeyname']) && empty($pconfig['ddnsdomainkey'])) {
1386
				$showadv = false;
1387
			} else {
1388
				$showadv = true;
1389
			}
1390
?>
1391
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1392 6e3488e9 Phil Davis
		} else {
1393 afe62c2b Phil Davis
			// It was a click, swap the state.
1394
			showadvdns = !showadvdns;
1395 6e3488e9 Phil Davis
		}
1396 afe62c2b Phil Davis
1397
		hideCheckbox('ddnsupdate', !showadvdns);
1398
		hideInput('ddnsdomain', !showadvdns);
1399
		hideInput('ddnsdomainprimary', !showadvdns);
1400
		hideInput('ddnsdomainkeyname', !showadvdns);
1401
		hideInput('ddnsdomainkey', !showadvdns);
1402
1403
		if (showadvdns) {
1404
			text = "<?=gettext('Hide Advanced');?>";
1405
		} else {
1406
			text = "<?=gettext('Display Advanced');?>";
1407
		}
1408
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1409 b5f6e690 Stephen Beaver
	}
1410
1411
	$('#btnadvdns').click(function(event) {
1412
		show_advdns();
1413
	});
1414
1415 afe62c2b Phil Davis
	// Show advanced MAC options ======================================================================================
1416 b5f6e690 Stephen Beaver
	var showadvmac = false;
1417
1418 afe62c2b Phil Davis
	function show_advmac(ispageload) {
1419
		var text;
1420
		// On page load decide the initial state based on the data.
1421
		if (ispageload) {
1422 8f8682f7 Phil Davis
<?php
1423 afe62c2b Phil Davis
			if (empty($pconfig['mac_allow']) && empty($pconfig['mac_deny'])) {
1424
				$showadv = false;
1425
			} else {
1426
				$showadv = true;
1427
			}
1428
?>
1429
			showadvmac = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1430 6e3488e9 Phil Davis
		} else {
1431 afe62c2b Phil Davis
			// It was a click, swap the state.
1432
			showadvmac = !showadvmac;
1433 6e3488e9 Phil Davis
		}
1434 b5f6e690 Stephen Beaver
1435 afe62c2b Phil Davis
		hideInput('mac_allow', !showadvmac);
1436
		hideInput('mac_deny', !showadvmac);
1437 b5f6e690 Stephen Beaver
1438 afe62c2b Phil Davis
		if (showadvmac) {
1439
			text = "<?=gettext('Hide Advanced');?>";
1440
		} else {
1441
			text = "<?=gettext('Display Advanced');?>";
1442
		}
1443
		$('#btnadvmac').html('<i class="fa fa-cog"></i> ' + text);
1444 b5f6e690 Stephen Beaver
	}
1445
1446
	$('#btnadvmac').click(function(event) {
1447 afe62c2b Phil Davis
		show_advmac();
1448 b5f6e690 Stephen Beaver
	});
1449
1450 afe62c2b Phil Davis
	// Show advanced NTP options ======================================================================================
1451 b5f6e690 Stephen Beaver
	var showadvntp = false;
1452
1453 afe62c2b Phil Davis
	function show_advntp(ispageload) {
1454
		var text;
1455
		// On page load decide the initial state based on the data.
1456
		if (ispageload) {
1457 8f8682f7 Phil Davis
<?php
1458 afe62c2b Phil Davis
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1459
				$showadv = false;
1460
			} else {
1461
				$showadv = true;
1462
			}
1463
?>
1464
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1465 6e3488e9 Phil Davis
		} else {
1466 afe62c2b Phil Davis
			// It was a click, swap the state.
1467
			showadvntp = !showadvntp;
1468 6e3488e9 Phil Davis
		}
1469 b5f6e690 Stephen Beaver
1470 afe62c2b Phil Davis
		hideInput('ntp1', !showadvntp);
1471
		hideInput('ntp2', !showadvntp);
1472 b5f6e690 Stephen Beaver
1473 afe62c2b Phil Davis
		if (showadvntp) {
1474
			text = "<?=gettext('Hide Advanced');?>";
1475
		} else {
1476
			text = "<?=gettext('Display Advanced');?>";
1477
		}
1478
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1479 b5f6e690 Stephen Beaver
	}
1480
1481
	$('#btnadvntp').click(function(event) {
1482
		show_advntp();
1483
	});
1484
1485 afe62c2b Phil Davis
	// Show advanced TFTP options ======================================================================================
1486
	var showadvtftp = false;
1487 b5f6e690 Stephen Beaver
1488 afe62c2b Phil Davis
	function show_advtftp(ispageload) {
1489
		var text;
1490
		// On page load decide the initial state based on the data.
1491
		if (ispageload) {
1492 8f8682f7 Phil Davis
<?php
1493 afe62c2b Phil Davis
			if (empty($pconfig['tftp'])) {
1494
				$showadv = false;
1495
			} else {
1496
				$showadv = true;
1497
			}
1498
?>
1499
			showadvtftp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1500 6e3488e9 Phil Davis
		} else {
1501 afe62c2b Phil Davis
			// It was a click, swap the state.
1502
			showadvtftp = !showadvtftp;
1503 6e3488e9 Phil Davis
		}
1504 b5f6e690 Stephen Beaver
1505 afe62c2b Phil Davis
		hideInput('tftp', !showadvtftp);
1506 b5f6e690 Stephen Beaver
1507 afe62c2b Phil Davis
		if (showadvtftp) {
1508
			text = "<?=gettext('Hide Advanced');?>";
1509
		} else {
1510
			text = "<?=gettext('Display Advanced');?>";
1511
		}
1512
		$('#btnadvtftp').html('<i class="fa fa-cog"></i> ' + text);
1513 b5f6e690 Stephen Beaver
	}
1514
1515
	$('#btnadvtftp').click(function(event) {
1516
		show_advtftp();
1517
	});
1518
1519 afe62c2b Phil Davis
	// Show advanced LDAP options ======================================================================================
1520 b5f6e690 Stephen Beaver
	var showadvldap = false;
1521
1522 afe62c2b Phil Davis
	function show_advldap(ispageload) {
1523
		var text;
1524
		// On page load decide the initial state based on the data.
1525
		if (ispageload) {
1526 8f8682f7 Phil Davis
<?php
1527 afe62c2b Phil Davis
			if (empty($pconfig['ldap'])) {
1528
				$showadv = false;
1529
			} else {
1530
				$showadv = true;
1531
			}
1532
?>
1533
			showadvldap = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1534 6e3488e9 Phil Davis
		} else {
1535 afe62c2b Phil Davis
			// It was a click, swap the state.
1536
			showadvldap = !showadvldap;
1537 6e3488e9 Phil Davis
		}
1538 b5f6e690 Stephen Beaver
1539 afe62c2b Phil Davis
		hideInput('ldap', !showadvldap);
1540 b5f6e690 Stephen Beaver
1541 afe62c2b Phil Davis
		if (showadvldap) {
1542
			text = "<?=gettext('Hide Advanced');?>";
1543
		} else {
1544
			text = "<?=gettext('Display Advanced');?>";
1545
		}
1546
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1547 b5f6e690 Stephen Beaver
	}
1548
1549
	$('#btnadvldap').click(function(event) {
1550
		show_advldap();
1551
	});
1552
1553 eef93144 Jared Dillard
	// Show advanced additional opts options ===========================================================================
1554 b5f6e690 Stephen Beaver
	var showadvopts = false;
1555
1556 afe62c2b Phil Davis
	function show_advopts(ispageload) {
1557
		var text;
1558
		// On page load decide the initial state based on the data.
1559
		if (ispageload) {
1560 8f8682f7 Phil Davis
<?php
1561 afe62c2b Phil Davis
			if (empty($pconfig['numberoptions']) ||
1562
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1563
				$showadv = false;
1564
			} else {
1565
				$showadv = true;
1566
			}
1567
?>
1568
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1569 6e3488e9 Phil Davis
		} else {
1570 afe62c2b Phil Davis
			// It was a click, swap the state.
1571
			showadvopts = !showadvopts;
1572 6e3488e9 Phil Davis
		}
1573 b5f6e690 Stephen Beaver
1574 afe62c2b Phil Davis
		hideClass('adnlopts', !showadvopts);
1575 b5f6e690 Stephen Beaver
1576 afe62c2b Phil Davis
		if (showadvopts) {
1577
			text = "<?=gettext('Hide Advanced');?>";
1578
		} else {
1579
			text = "<?=gettext('Display Advanced');?>";
1580
		}
1581
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1582 b5f6e690 Stephen Beaver
	}
1583
1584
	$('#btnadvopts').click(function(event) {
1585
		show_advopts();
1586
	});
1587
1588 68de2169 Phil Davis
	// Show advanced Network Booting options ===========================================================================
1589
	var showadvnwkboot = false;
1590
1591
	function show_advnwkboot(ispageload) {
1592
		var text;
1593
		// On page load decide the initial state based on the data.
1594
		if (ispageload) {
1595
<?php
1596
			if (empty($pconfig['netboot'])) {
1597
				$showadv = false;
1598
			} else {
1599
				$showadv = true;
1600
			}
1601
?>
1602
			showadvnwkboot = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1603
		} else {
1604
			// It was a click, swap the state.
1605
			showadvnwkboot = !showadvnwkboot;
1606
		}
1607
1608
		hideCheckbox('netboot', !showadvnwkboot);
1609
		hideInput('nextserver', !showadvnwkboot);
1610
		hideInput('filename', !showadvnwkboot);
1611
		hideInput('filename32', !showadvnwkboot);
1612
		hideInput('filename64', !showadvnwkboot);
1613
		hideInput('rootpath', !showadvnwkboot);
1614
1615
		if (showadvnwkboot) {
1616
			text = "<?=gettext('Hide Advanced');?>";
1617
		} else {
1618
			text = "<?=gettext('Display Advanced');?>";
1619
		}
1620
		$('#btnadvnwkboot').html('<i class="fa fa-cog"></i> ' + text);
1621
	}
1622
1623
	$('#btnadvnwkboot').click(function(event) {
1624
		show_advnwkboot();
1625
	});
1626
1627 eef93144 Jared Dillard
	// ---------- On initial page load ------------------------------------------------------------
1628
1629 afe62c2b Phil Davis
	show_advdns(true);
1630
	show_advmac(true);
1631
	show_advntp(true);
1632
	show_advtftp(true);
1633
	show_advldap(true);
1634
	show_advopts(true);
1635 68de2169 Phil Davis
	show_advnwkboot(true);
1636 0bc61baa Stephen Beaver
1637
	// Suppress "Delete row" button if there are fewer than two rows
1638
	checkLastRow();
1639 b5f6e690 Stephen Beaver
});
1640 180db186 Colin Fleming
//]]>
1641 5b237745 Scott Ullrich
</script>
1642 b5f6e690 Stephen Beaver
1643 3c9befb9 Chris Buechler
<?php include("foot.inc");