Project

General

Profile

Download (38.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * services_dhcpv6.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2019 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2010 Seth Mos <seth.mos@dds.nl>
10
 * All rights reserved.
11
 *
12
 * originally based on m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15
 *
16
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27
 */
28

    
29
##|+PRIV
30
##|*IDENT=page-services-dhcpv6server
31
##|*NAME=Services: DHCPv6 Server
32
##|*DESCR=Allow access to the 'Services: DHCPv6 Server' page.
33
##|*MATCH=services_dhcpv6.php*
34
##|-PRIV
35

    
36
require_once("guiconfig.inc");
37
require_once("filter.inc");
38

    
39
function dhcpv6_apply_changes($dhcpdv6_enable_changed) {
40
	$retval = 0;
41
	$retvaldhcp = 0;
42
	$retvaldns = 0;
43
	/* Stop DHCPv6 so we can cleanup leases */
44
	killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
45
	// dhcp_clean_leases();
46
	/* dnsmasq_configure calls dhcpd_configure */
47
	/* no need to restart dhcpd twice */
48
	if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic']))	{
49
		$retvaldns |= services_dnsmasq_configure();
50
		if ($retvaldns == 0) {
51
			clear_subsystem_dirty('hosts');
52
			clear_subsystem_dirty('staticmaps');
53
		}
54
	} else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) {
55
		$retvaldns |= services_unbound_configure();
56
		if ($retvaldns == 0) {
57
			clear_subsystem_dirty('unbound');
58
			clear_subsystem_dirty('staticmaps');
59
		}
60
	} else {
61
		$retvaldhcp |= services_dhcpd_configure();
62
		if ($retvaldhcp == 0) {
63
			clear_subsystem_dirty('staticmaps');
64
		}
65
	}
66
	/* BIND package - Bug #3710 */
67
	if (!function_exists('is_package_installed')) {
68
		require_once('pkg-utils.inc');
69
	}
70
	if (is_package_installed('pfSense-pkg-bind') && isset($config['installedpackages']['bind']['config'][0]['enable_bind'])) {
71
		$reloadbind = false;
72
		if (is_array($config['installedpackages']['bindzone'])) {
73
			$bindzone = $config['installedpackages']['bindzone']['config'];
74
		} else {
75
			$bindzone = array();
76
		}
77
		for ($x = 0; $x < sizeof($bindzone); $x++) {
78
			$zone = $bindzone[$x];
79
			if ($zone['regdhcpstatic'] == 'on') {
80
				$reloadbind = true;
81
				break;
82
			}
83
		}
84
		if ($reloadbind === true) {
85
			if (file_exists("/usr/local/pkg/bind.inc")) {
86
				require_once("/usr/local/pkg/bind.inc");
87
				bind_sync();
88
			}
89
		}
90
	}
91
	if ($dhcpdv6_enable_changed) {
92
		$retvalfc |= filter_configure();
93
	}
94
	if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) {
95
		$retval = 1;
96
	}
97
	return $retval;
98
}
99

    
100
if (!$g['services_dhcp_server_enable']) {
101
	header("Location: /");
102
	exit;
103
}
104

    
105
$if = $_REQUEST['if'];
106
$iflist = get_configured_interface_with_descr();
107
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
108

    
109
/* set the starting interface */
110
if (!$if || !isset($iflist[$if])) {
111
	foreach ($iflist as $ifent => $ifname) {
112
		$oc = $config['interfaces'][$ifent];
113
		$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
114
		    (is_ipaddrv6($oc['ipaddrv6']) &&
115
		    !is_linklocal($oc['ipaddrv6'])));
116

    
117
		if ((!is_array($config['dhcpdv6'][$ifent]) ||
118
		    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
119
		    !$valid_if_ipaddrv6) {
120
			continue;
121
		}
122
		$if = $ifent;
123
		break;
124
	}
125
}
126

    
127
if (is_array($config['dhcpdv6'][$if])) {
128
	/* DHCPv6 */
129
	if (is_array($config['dhcpdv6'][$if]['range'])) {
130
		$pconfig['range_from'] = $config['dhcpdv6'][$if]['range']['from'];
131
		$pconfig['range_to'] = $config['dhcpdv6'][$if]['range']['to'];
132
	}
133
	if (is_array($config['dhcpdv6'][$if]['prefixrange'])) {
134
		$pconfig['prefixrange_from'] = $config['dhcpdv6'][$if]['prefixrange']['from'];
135
		$pconfig['prefixrange_to'] = $config['dhcpdv6'][$if]['prefixrange']['to'];
136
		$pconfig['prefixrange_length'] = $config['dhcpdv6'][$if]['prefixrange']['prefixlength'];
137
	}
138
	$pconfig['deftime'] = $config['dhcpdv6'][$if]['defaultleasetime'];
139
	$pconfig['maxtime'] = $config['dhcpdv6'][$if]['maxleasetime'];
140
	$pconfig['domain'] = $config['dhcpdv6'][$if]['domain'];
141
	$pconfig['domainsearchlist'] = $config['dhcpdv6'][$if]['domainsearchlist'];
142
	list($pconfig['wins1'], $pconfig['wins2']) = $config['dhcpdv6'][$if]['winsserver'];
143
	list($pconfig['dns1'], $pconfig['dns2'], $pconfig['dns3'], $pconfig['dns4']) = $config['dhcpdv6'][$if]['dnsserver'];
144
	$pconfig['enable'] = isset($config['dhcpdv6'][$if]['enable']);
145
	$pconfig['ddnsdomain'] = $config['dhcpdv6'][$if]['ddnsdomain'];
146
	$pconfig['ddnsdomainprimary'] = $config['dhcpdv6'][$if]['ddnsdomainprimary'];
147
	$pconfig['ddnsdomainkeyname'] = $config['dhcpdv6'][$if]['ddnsdomainkeyname'];
148
	$pconfig['ddnsdomainkeyalgorithm'] = $config['dhcpdv6'][$if]['ddnsdomainkeyalgorithm'];
149
	$pconfig['ddnsdomainkey'] = $config['dhcpdv6'][$if]['ddnsdomainkey'];
150
	$pconfig['ddnsupdate'] = isset($config['dhcpdv6'][$if]['ddnsupdate']);
151
	$pconfig['ddnsforcehostname'] = isset($config['dhcpdv6'][$if]['ddnsforcehostname']);
152
	$pconfig['ddnsreverse'] = isset($config['dhcpdv6'][$if]['ddnsreverse']);
153
	$pconfig['ddnsclientupdates'] = $config['dhcpdv6'][$if]['ddnsclientupdates'];
154
	list($pconfig['ntp1'], $pconfig['ntp2']) = $config['dhcpdv6'][$if]['ntpserver'];
155
	$pconfig['tftp'] = $config['dhcpdv6'][$if]['tftp'];
156
	$pconfig['ldap'] = $config['dhcpdv6'][$if]['ldap'];
157
	$pconfig['netboot'] = isset($config['dhcpdv6'][$if]['netboot']);
158
	$pconfig['bootfile_url'] = $config['dhcpdv6'][$if]['bootfile_url'];
159
	$pconfig['netmask'] = $config['dhcpdv6'][$if]['netmask'];
160
	$pconfig['numberoptions'] = $config['dhcpdv6'][$if]['numberoptions'];
161
	$pconfig['dhcpv6leaseinlocaltime'] = $config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'];
162
	if (!is_array($config['dhcpdv6'][$if]['staticmap'])) {
163
		$config['dhcpdv6'][$if]['staticmap'] = array();
164
	}
165
	init_config_arr(array('dhcpdv6', $if, 'staticmap'));
166
	$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
167
}
168

    
169
if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
170
	$trackifname = $config['interfaces'][$if]['track6-interface'];
171
	$trackcfg = $config['interfaces'][$trackifname];
172
	$ifcfgsn = "64";
173
	$ifcfgip = '::';
174

    
175
	$str_help_mask = dhcpv6_pd_str_help($ifcfgsn);
176
} else {
177
	$ifcfgip = get_interface_ipv6($if);
178
	$ifcfgsn = get_interface_subnetv6($if);
179
}
180

    
181
/*	 set the enabled flag which will tell us if DHCP relay is enabled
182
 *	 on any interface. We will use this to disable DHCP server since
183
 *	 the two are not compatible with each other.
184
 */
185

    
186
$dhcrelay_enabled = false;
187
$dhcrelaycfg = $config['dhcrelay6'];
188

    
189
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
190
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
191

    
192
	foreach ($dhcrelayifs as $dhcrelayif) {
193

    
194
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
195
			$dhcrelay_enabled = true;
196
			break;
197
		}
198
	}
199
}
200

    
201
if (isset($_POST['apply'])) {
202
	$changes_applied = true;
203
	$retval = dhcpv6_apply_changes(false);
204
} elseif (isset($_POST['save'])) {
205
	unset($input_errors);
206

    
207
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
208
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
209
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
210

    
211
	$pconfig = $_POST;
212

    
213
	$numberoptions = array();
214
	for ($x = 0; $x < 99; $x++) {
215
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
216
			$numbervalue = array();
217
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
218
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
219
			$numberoptions['item'][] = $numbervalue;
220
		}
221
	}
222
	// Reload the new pconfig variable that the form uses.
223
	$pconfig['numberoptions'] = $numberoptions;
224

    
225
	/* input validation */
226

    
227
	// Note: if DHCPv6 Server is not enabled, then it is OK to adjust other parameters without specifying range from-to.
228
	if ($_POST['enable']) {
229
		$reqdfields = explode(" ", "range_from range_to");
230
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
231

    
232
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
233
	}
234

    
235
	if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
236
		$input_errors[] = gettext("A valid prefix range must be specified.");
237
	}
238
	if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
239
		$input_errors[] = gettext("A valid prefix range must be specified.");
240
	}
241

    
242
	if ($_POST['prefixrange_from'] && $_POST['prefixrange_to'] &&
243
		$_POST['prefixrange_length']) {
244
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_from'],
245
			$_POST['prefixrange_length']);
246
		$netmask = text_to_compressed_ip6($netmask);
247

    
248
		if ($netmask != text_to_compressed_ip6(strtolower(
249
			$_POST['prefixrange_from']))) {
250
			$input_errors[] = sprintf(gettext(
251
				"Prefix Delegation From address is not a valid IPv6 Netmask for %s"),
252
				$netmask . '/' . $_POST['prefixrange_length']);
253
		}
254

    
255
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
256
			$_POST['prefixrange_length']);
257
		$netmask = text_to_compressed_ip6($netmask);
258

    
259
		if ($netmask != text_to_compressed_ip6(strtolower(
260
			$_POST['prefixrange_to']))) {
261
			$input_errors[] = sprintf(gettext(
262
				"Prefix Delegation To address is not a valid IPv6 Netmask for %s"),
263
				$netmask . '/' . $_POST['prefixrange_length']);
264
		}
265
	}
266

    
267
	$range_from_to_ok = true;
268

    
269
	if ($_POST['range_from']) {
270
		if (!is_ipaddrv6($_POST['range_from'])) {
271
			$input_errors[] = gettext("A valid range must be specified.");
272
			$range_from_to_ok = false;
273
		} elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
274
			!Net_IPv6::isInNetmask($_POST['range_from'], '::', $ifcfgsn)) {
275
			$input_errors[] = sprintf(gettext(
276
				'The prefix (upper %1$s bits) must be zero.  Use the form %2$s'),
277
				$ifcfgsn, $str_help_mask);
278
			$range_from_to_ok = false;
279
		}
280
	}
281
	if ($_POST['range_to']) {
282
		if (!is_ipaddrv6($_POST['range_to'])) {
283
			$input_errors[] = gettext("A valid range must be specified.");
284
			$range_from_to_ok = false;
285
		} elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
286
			!Net_IPv6::isInNetmask($_POST['range_to'], '::', $ifcfgsn)) {
287
			$input_errors[] = sprintf(gettext(
288
				'The prefix (upper %1$s bits) must be zero.  Use the form %2$s'),
289
				$ifcfgsn, $str_help_mask);
290
			$range_from_to_ok = false;
291
		}
292
	}
293
	if (($_POST['range_from'] && !$_POST['range_to']) || ($_POST['range_to'] && !$_POST['range_from'])) {
294
		$input_errors[] = gettext("Range From and Range To must both be entered.");
295
	}
296
	if (($_POST['gateway'] && !is_ipaddrv6($_POST['gateway']))) {
297
		$input_errors[] = gettext("A valid IPv6 address must be specified for the gateway.");
298
	}
299
	if (($_POST['dns1'] && !is_ipaddrv6($_POST['dns1'])) ||
300
		($_POST['dns2'] && !is_ipaddrv6($_POST['dns2'])) ||
301
		($_POST['dns3'] && !is_ipaddrv6($_POST['dns3'])) ||
302
		($_POST['dns4'] && !is_ipaddrv6($_POST['dns4']))) {
303
		$input_errors[] = gettext("A valid IPv6 address must be specified for each of the DNS servers.");
304
	}
305

    
306
	if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
307
		$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
308
	}
309
	if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
310
		$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
311
	}
312
	if ($_POST['ddnsupdate'] && !is_domain($_POST['ddnsdomain'])) {
313
		$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
314
	}
315
	if ($_POST['ddnsupdate'] && !is_ipaddrv4($_POST['ddnsdomainprimary'])) {
316
		$input_errors[] = gettext("A valid primary domain name server IPv4 address must be specified for the dynamic domain name.");
317
	}
318
	if ($_POST['ddnsupdate'] && (!$_POST['ddnsdomainkeyname'] || !$_POST['ddnsdomainkeyalgorithm'] || !$_POST['ddnsdomainkey'])) {
319
		$input_errors[] = gettext("A valid domain key name, algorithm and secret must be specified.");
320
	}
321
	if ($_POST['domainsearchlist']) {
322
		$domain_array = preg_split("/[ ;]+/", $_POST['domainsearchlist']);
323
		foreach ($domain_array as $curdomain) {
324
			if (!is_domain($curdomain)) {
325
				$input_errors[] = gettext("A valid domain search list must be specified.");
326
				break;
327
			}
328
		}
329
	}
330

    
331
	if (($_POST['ntp1'] && !is_ipaddrv6($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv6($_POST['ntp2']))) {
332
		$input_errors[] = gettext("A valid IPv6 address must be specified for the primary/secondary NTP servers.");
333
	}
334
	if (($_POST['domain'] && !is_domain($_POST['domain']))) {
335
		$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
336
	}
337
	if ($_POST['tftp'] && !is_ipaddr($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
338
		$input_errors[] = gettext("A valid IPv6 address or hostname must be specified for the TFTP server.");
339
	}
340
	if (($_POST['bootfile_url'] && !is_URL($_POST['bootfile_url']))) {
341
		$input_errors[] = gettext("A valid URL must be specified for the network bootfile.");
342
	}
343

    
344
	// Disallow a range that includes the virtualip
345
	if ($range_from_to_ok && is_array($config['virtualip']['vip'])) {
346
		foreach ($config['virtualip']['vip'] as $vip) {
347
			if ($vip['interface'] == $if) {
348
				if ($vip['subnetv6'] && is_inrange_v6($vip['subnetv6'], $_POST['range_from'], $_POST['range_to'])) {
349
					$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IPv6 address %s."), $vip['subnetv6']);
350
				}
351
			}
352
		}
353
	}
354

    
355
	$noip = false;
356
	if (is_array($a_maps)) {
357
		foreach ($a_maps as $map) {
358
			if (empty($map['ipaddrv6'])) {
359
				$noip = true;
360
			}
361
		}
362
	}
363

    
364
	/* make sure that the DHCP Relay isn't enabled on this interface */
365
	if ($_POST['enable'] && $dhcrelay_enabled) {
366
		$input_errors[] = sprintf(gettext("The DHCP relay on the %s interface must be disabled before enabling the DHCP server."), $iflist[$if]);
367
	}
368

    
369
	// If nothing is wrong so far, and we have range from and to, then check conditions related to the values of range from and to.
370
	if (!$input_errors && $_POST['range_from'] && $_POST['range_to']) {
371
		/* make sure the range lies within the current subnet */
372
		$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
373
		$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
374

    
375
		if (is_ipaddrv6($ifcfgip)) {
376
			if ((!is_inrange_v6($_POST['range_from'], $subnet_start, $subnet_end)) ||
377
				(!is_inrange_v6($_POST['range_to'], $subnet_start, $subnet_end))) {
378
				$input_errors[] = gettext("The specified range lies outside of the current subnet.");
379
			}
380
		}
381
		/* "from" cannot be higher than "to" */
382
		if (inet_pton($_POST['range_from']) > inet_pton($_POST['range_to'])) {
383
			$input_errors[] = gettext("The range is invalid (first element higher than second element).");
384
		}
385

    
386
		/* Verify static mappings do not overlap:
387
		   - available DHCP range
388
		   - prefix delegation range (FIXME: still need to be completed) */
389
		$dynsubnet_start = inet_pton($_POST['range_from']);
390
		$dynsubnet_end = inet_pton($_POST['range_to']);
391

    
392
		if (is_array($a_maps)) {
393
			foreach ($a_maps as $map) {
394
				if (empty($map['ipaddrv6'])) {
395
					continue;
396
				}
397
				if ((inet_pton($map['ipaddrv6']) > $dynsubnet_start) &&
398
					(inet_pton($map['ipaddrv6']) < $dynsubnet_end)) {
399
					$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
400
					break;
401
				}
402
			}
403
		}
404
	}
405

    
406
	if (!$input_errors) {
407
		if (!is_array($config['dhcpdv6'])) {
408
			$config['dhcpdv6'] = array();
409
		}
410
		if (!is_array($config['dhcpdv6'][$if])) {
411
			$config['dhcpdv6'][$if] = array();
412
		}
413
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
414
			$config['dhcpdv6'][$if]['range'] = array();
415
		}
416
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
417
			$config['dhcpdv6'][$if]['prefixrange'] = array();
418
		}
419

    
420
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
421
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
422
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
423
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
424
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
425
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
426
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
427
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
428

    
429
		unset($config['dhcpdv6'][$if]['winsserver']);
430

    
431
		unset($config['dhcpdv6'][$if]['dnsserver']);
432
		if ($_POST['dns1']) {
433
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
434
		}
435
		if ($_POST['dns2']) {
436
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
437
		}
438
		if ($_POST['dns3']) {
439
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
440
		}
441
		if ($_POST['dns4']) {
442
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
443
		}
444

    
445
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
446
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
447
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
448
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
449
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
450
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
451
		$config['dhcpdv6'][$if]['ddnsdomainkeyalgorithm'] = $_POST['ddnsdomainkeyalgorithm'];
452
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
453
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
454
		$config['dhcpdv6'][$if]['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
455
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
456
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
457

    
458
		unset($config['dhcpdv6'][$if]['ntpserver']);
459
		if ($_POST['ntp1']) {
460
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
461
		}
462
		if ($_POST['ntp2']) {
463
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
464
		}
465

    
466
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
467
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
468
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
469
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
470
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
471

    
472
		// Handle the custom options rowhelper
473
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
474
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
475
		}
476

    
477
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
478

    
479
		write_config();
480

    
481
		$changes_applied = true;
482
		$retval = dhcpv6_apply_changes($dhcpdv6_enable_changed);
483
	}
484
}
485

    
486
if ($_POST['act'] == "del") {
487
	if ($a_maps[$_POST['id']]) {
488
		unset($a_maps[$_POST['id']]);
489
		write_config();
490
		if (isset($config['dhcpdv6'][$if]['enable'])) {
491
			mark_subsystem_dirty('staticmapsv6');
492
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstaticv6'])) {
493
				mark_subsystem_dirty('hosts');
494
			}
495
		}
496
		header("Location: services_dhcpv6.php?if={$if}");
497
		exit;
498
	}
499
}
500

    
501
$pgtitle = array(gettext("Services"), htmlspecialchars(gettext("DHCPv6 Server & RA")));
502
$pglinks = array("", "services_dhcpv6.php");
503

    
504
if (!empty($if) && isset($iflist[$if])) {
505
	$pgtitle[] = $iflist[$if];
506
	$pglinks[] = "@self";
507
	$pgtitle[] = gettext("DHCPv6 Server");
508
	$pglinks[] = "@self";
509
}
510
$shortcut_section = "dhcp6";
511

    
512
include("head.inc");
513

    
514
if ($input_errors) {
515
	print_input_errors($input_errors);
516
}
517

    
518
if ($changes_applied) {
519
	print_apply_result_box($retval);
520
}
521

    
522
if (is_subsystem_dirty('staticmaps')) {
523
	print_apply_box(gettext('The static mapping configuration has been changed.') . '<br />' . gettext('The changes must be applied for them to take effect.'));
524
}
525

    
526
/* active tabs */
527
$tab_array = array();
528
$tabscounter = 0;
529
$i = 0;
530

    
531
foreach ($iflist as $ifent => $ifname) {
532
	$oc = $config['interfaces'][$ifent];
533
	$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
534
	    (is_ipaddrv6($oc['ipaddrv6']) &&
535
	    !is_linklocal($oc['ipaddrv6'])));
536

    
537
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
538
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
539
	    !$valid_if_ipaddrv6) {
540
		continue;
541
	}
542

    
543
	if ($ifent == $if) {
544
		$active = true;
545
	} else {
546
		$active = false;
547
	}
548

    
549
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
550
	$tabscounter++;
551
}
552

    
553
/* tack on PPPoE or PPtP servers here */
554
/* pppoe server */
555
if (is_array($config['pppoes']['pppoe'])) {
556
	foreach ($config['pppoes']['pppoe'] as $pppoe) {
557
		if ($pppoe['mode'] == "server") {
558
			$ifent = "poes". $pppoe['pppoeid'];
559
			$ifname = strtoupper($ifent);
560

    
561
			if ($ifent == $if) {
562
				$active = true;
563
			} else {
564
				$active = false;
565
			}
566

    
567
			$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
568
			$tabscounter++;
569
		}
570
	}
571
}
572

    
573
if ($tabscounter == 0) {
574
	print_info_box(gettext("The DHCPv6 Server can only be enabled on interfaces configured with a static IPv6 address. This system has none."), 'danger');
575
	include("foot.inc");
576
	exit;
577
}
578

    
579
display_top_tabs($tab_array);
580

    
581
$tab_array = array();
582
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
583
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
584
display_top_tabs($tab_array, false, 'nav nav-tabs');
585

    
586
$form = new Form();
587

    
588
$section = new Form_Section('DHCPv6 Options');
589

    
590
if ($dhcrelay_enabled) {
591
	$section->addInput(new Form_Checkbox(
592
		'enable',
593
		'DHCPv6 Server',
594
		gettext("DHCPv6 Relay is currently enabled. DHCPv6 Server canot be enabled while the DHCPv6 Relay is enabled on any interface."),
595
		$pconfig['enable']
596
	))->setAttribute('disabled', true);
597
} else {
598
	$section->addInput(new Form_Checkbox(
599
		'enable',
600
		'DHCPv6 Server',
601
		'Enable DHCPv6 server on interface ' . $iflist[$if],
602
		$pconfig['enable']
603
	));
604
}
605

    
606
if (is_ipaddrv6($ifcfgip)) {
607

    
608
	if ($ifcfgip == "::") {
609
		$sntext = "Prefix Delegation";
610
	} else {
611
		$sntext = gen_subnetv6($ifcfgip, $ifcfgsn);
612
	}
613
	$section->addInput(new Form_StaticText(
614
		'Subnet',
615
		$sntext
616
		));
617

    
618
	$section->addInput(new Form_StaticText(
619
		'Subnet Mask',
620
		$ifcfgsn . ' bits'
621
		));
622

    
623
	$section->addInput(new Form_StaticText(
624
		'Available Range',
625
		$range_from = gen_subnetv6($ifcfgip, $ifcfgsn) . ' to ' . gen_subnetv6_max($ifcfgip, $ifcfgsn)
626
		))->setHelp($trackifname ? 'Prefix Delegation subnet will be appended to the beginning of the defined range':'');
627
}
628

    
629
$f1 = new Form_Input(
630
	'range_from',
631
	null,
632
	'text',
633
	$pconfig['range_from']
634
);
635

    
636
$f1->setHelp('From');
637

    
638
$f2 = new Form_Input(
639
	'range_to',
640
	null,
641
	'text',
642
	$pconfig['range_to']
643
);
644

    
645
$f2->setHelp('To');
646

    
647
$group = new Form_Group('*Range');
648

    
649
$group->add($f1);
650
$group->add($f2);
651

    
652
$section->add($group);
653

    
654
$f1 = new Form_Input(
655
	'prefixrange_from',
656
	null,
657
	'text',
658
	$pconfig['prefixrange_from']
659
);
660

    
661
$f1->setHelp('From');
662

    
663
$f2 = new Form_Input(
664
	'prefixrange_to',
665
	null,
666
	'text',
667
	$pconfig['prefixrange_to']
668
);
669

    
670
$f2->setHelp('To');
671

    
672
$group = new Form_Group('Prefix Delegation Range');
673

    
674
$group->add($f1);
675
$group->add($f2);
676

    
677
$section->add($group);
678

    
679
$section->addInput(new Form_Select(
680
	'prefixrange_length',
681
	'Prefix Delegation Size',
682
	$pconfig['prefixrange_length'],
683
	array(
684
		'48' => '48',
685
		'52' => '52',
686
		'56' => '56',
687
		'59' => '59',
688
		'60' => '60',
689
		'61' => '61',
690
		'62' => '62',
691
		'63' => '63',
692
		'64' => '64'
693
		)
694
))->setHelp('A Prefix range can be defined here for DHCP Prefix Delegation. This allows for assigning networks to subrouters. The start and end of the range must end on boundaries of the prefix delegation size.');
695

    
696
$group = new Form_Group('DNS Servers');
697

    
698
for ($i=1;$i<=4; $i++) {
699
	$group->add(new Form_input(
700
		'dns' . $i,
701
		null,
702
		'text',
703
		$pconfig['dns' . $i],
704
		['placeholder' => 'DNS ' . $i]
705
	));
706
}
707

    
708
$group->setHelp('Leave blank to use the system default DNS servers, this interface\'s IP if DNS forwarder is enabled, or the servers configured on the "General" page.');
709
$section->add($group);
710

    
711
$section->addInput(new Form_Input(
712
	'domain',
713
	'Domain name',
714
	'text',
715
	$pconfig['domain']
716
))->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. ');
717

    
718
$section->addInput(new Form_Input(
719
	'domainsearchlist',
720
	'Domain search list',
721
	'text',
722
	$pconfig['domainsearchlist']
723
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
724

    
725
$section->addInput(new Form_Input(
726
	'deftime',
727
	'Default lease time',
728
	'text',
729
	$pconfig['deftime']
730
))->setHelp('Lease time in seconds. Used for clients that do not ask for a specific expiration time. %1$s' .
731
			'The default is 7200 seconds.', '<br />');
732

    
733
$section->addInput(new Form_Input(
734
	'maxtime',
735
	'Max lease time',
736
	'text',
737
	$pconfig['maxtime']
738
))->setHelp('Maximum lease time for clients that ask for a specific expiration time. %1$s' .
739
			'The default is 86400 seconds.', '<br />');
740

    
741
$section->addInput(new Form_Checkbox(
742
	'dhcpv6leaseinlocaltime',
743
	'Time Format Change',
744
	'Change DHCPv6 display lease time from UTC to local time',
745
	$pconfig['dhcpv6leaseinlocaltime']
746
))->setHelp('By default DHCPv6 leases are displayed in UTC time. ' .
747
			'By checking this box DHCPv6 lease time will be displayed in local time and set to time zone selected. ' .
748
			'This will be used for all DHCPv6 interfaces lease time.');
749

    
750
$btnadv = new Form_Button(
751
	'btnadvdns',
752
	'Display Advanced',
753
	null,
754
	'fa-cog'
755
);
756

    
757
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
758

    
759
$section->addInput(new Form_StaticText(
760
	'Dynamic DNS',
761
	$btnadv
762
));
763

    
764
$section->addInput(new Form_Checkbox(
765
	'ddnsupdate',
766
	'DHCP Registration',
767
	'Enable registration of DHCP client names in DNS.',
768
	$pconfig['ddnsupdate']
769
));
770

    
771
$section->addInput(new Form_Input(
772
	'ddnsdomain',
773
	'DDNS Domain',
774
	'text',
775
	$pconfig['ddnsdomain']
776
))->setHelp('Enter the dynamic DNS domain which will be used to register client names in the DNS server.');
777

    
778
$section->addInput(new Form_Checkbox(
779
	'ddnsforcehostname',
780
	'DDNS Hostnames',
781
	'Force dynamic DNS hostname to be the same as configured hostname for Static Mappings',
782
	$pconfig['ddnsforcehostname']
783
))->setHelp('Default registers host name option supplied by DHCP client.');
784

    
785
$section->addInput(new Form_IpAddress(
786
	'ddnsdomainprimary',
787
	'DDNS Server IP',
788
	$pconfig['ddnsdomainprimary'],
789
	'V4'
790
))->setHelp('Enter the primary domain name server IPv4 address for the dynamic domain name.');
791

    
792
$section->addInput(new Form_Input(
793
	'ddnsdomainkeyname',
794
	'DDNS Domain Key name',
795
	'text',
796
	$pconfig['ddnsdomainkeyname']
797
))->setHelp('Enter the dynamic DNS domain key name which will be used to register client names in the DNS server.');
798

    
799
$section->addInput(new Form_Select(
800
	'ddnsdomainkeyalgorithm',
801
	'Key algorithm',
802
	$pconfig['ddnsdomainkeyalgorithm'],
803
	array(
804
		'hmac-md5' => 'HMAC-MD5 (legacy default)',
805
		'hmac-sha1' => 'HMAC-SHA1',
806
		'hmac-sha224' => 'HMAC-SHA224',
807
		'hmac-sha256' => 'HMAC-SHA256 (current bind9 default)',
808
		'hmac-sha384' => 'HMAC-SHA384',
809
		'hmac-sha512' => 'HMAC-SHA512 (most secure)',
810
	)
811
));
812

    
813
$section->addInput(new Form_Input(
814
	'ddnsdomainkey',
815
	'DDNS Domain Key secret',
816
	'text',
817
	$pconfig['ddnsdomainkey']
818
))->setHelp('Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.');
819

    
820
$section->addInput(new Form_Select(
821
	'ddnsclientupdates',
822
	'DDNS Client Updates',
823
	$pconfig['ddnsclientupdates'],
824
	array(
825
	    'allow' => gettext('Allow'),
826
	    'deny' => gettext('Deny'),
827
	    'ignore' => gettext('Ignore'))
828
))->setHelp('How Forward entries are handled when client indicates they wish to update DNS.  ' .
829
	    'Allow prevents DHCP from updating Forward entries, Deny indicates that DHCP will ' .
830
	    'do the updates and the client should not, Ignore specifies that DHCP will do the ' .
831
	    'update and the client can also attempt the update usually using a different domain name.');
832

    
833
$section->addInput(new Form_Checkbox(
834
	'ddnsreverse',
835
	'DDNS Reverse',
836
	'Add reverse dynamic DNS entries.',
837
	$pconfig['ddnsreverse']
838
));
839

    
840
$btnadv = new Form_Button(
841
	'btnadvntp',
842
	'Display Advanced',
843
	null,
844
	'fa-cog'
845
);
846

    
847
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
848

    
849
$section->addInput(new Form_StaticText(
850
	'NTP servers',
851
	$btnadv
852
));
853

    
854
$group = new Form_Group('NTP Servers');
855

    
856
$group->add(new Form_Input(
857
	'ntp1',
858
	'NTP Server 1',
859
	'text',
860
	$pconfig['ntp1'],
861
	['placeholder' => 'NTP 1']
862
));
863

    
864
$group->add(new Form_Input(
865
	'ntp2',
866
	'NTP Server 2',
867
	'text',
868
	$pconfig['ntp2'],
869
	['placeholder' => 'NTP 2']
870
));
871

    
872
$group->addClass('ntpclass');
873

    
874
$section->add($group);
875

    
876
$btnadv = new Form_Button(
877
	'btnadvldap',
878
	'Display Advanced',
879
	null,
880
	'fa-cog'
881
);
882

    
883
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
884

    
885
$section->addInput(new Form_StaticText(
886
	'LDAP',
887
	$btnadv
888
));
889

    
890
$section->addInput(new Form_Input(
891
	'ldap',
892
	'LDAP URI',
893
	'text',
894
	$pconfig['ldap']
895
));
896

    
897
$btnadv = new Form_Button(
898
	'btnadvnetboot',
899
	'Display Advanced',
900
	null,
901
	'fa-cog'
902
);
903

    
904
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
905

    
906
$section->addInput(new Form_StaticText(
907
	'Network booting',
908
	$btnadv
909
));
910

    
911
$section->addInput(new Form_Checkbox(
912
	'netboot',
913
	'Network booting',
914
	'Enable Network Booting',
915
	$pconfig['netboot']
916
));
917

    
918
$section->addInput(new Form_Input(
919
	'bootfile_url',
920
	'Bootfile URL',
921
	'text',
922
	$pconfig['bootfile_url']
923
));
924

    
925
$btnadv = new Form_Button(
926
	'btnadvopts',
927
	'Display Advanced',
928
	null,
929
	'fa-cog'
930
);
931

    
932
$btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
933

    
934
$section->addInput(new Form_StaticText(
935
	'Additional BOOTP/DHCP Options',
936
	$btnadv
937
));
938

    
939
$form->add($section);
940

    
941
$title = 'Show Additional BOOTP/DHCP Options';
942

    
943
if (!$pconfig['numberoptions']) {
944
	$noopts = true;
945
	$pconfig['numberoptions'] = array();
946
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
947
} else {
948
	$noopts = false;
949
}
950

    
951
$counter = 0;
952
if (!is_array($pconfig['numberoptions'])) {
953
	$pconfig['numberoptions'] = array();
954
}
955
if (!is_array($pconfig['numberoptions']['item'])) {
956
	$pconfig['numberoptions']['item'] = array();
957
}
958
$last = count($pconfig['numberoptions']['item']) - 1;
959

    
960
foreach ($pconfig['numberoptions']['item'] as $item) {
961
	$group = new Form_Group(null);
962
	$group->addClass('repeatable');
963
	$group->addClass('adnloptions');
964

    
965
	$group->add(new Form_Input(
966
		'number' . $counter,
967
		null,
968
		'text',
969
		$item['number']
970
	))->setHelp($counter == $last ? 'Number':null);
971

    
972
	$group->add(new Form_Input(
973
		'value' . $counter,
974
		null,
975
		'text',
976
		base64_decode($item['value'])
977
	))->setHelp($counter == $last ? 'Value':null);
978

    
979
	$btn = new Form_Button(
980
		'deleterow' . $counter,
981
		'Delete',
982
		null,
983
		'fa-trash'
984
	);
985

    
986
	$btn->addClass('btn-warning');
987
	$group->add($btn);
988
	$section->add($group);
989
	$counter++;
990
}
991

    
992

    
993
$btnaddopt = new Form_Button(
994
	'addrow',
995
	'Add Option',
996
	null,
997
	'fa-plus'
998
);
999

    
1000
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
1001

    
1002
$section->addInput($btnaddopt);
1003

    
1004
$form->addGlobal(new Form_Input(
1005
	'if',
1006
	null,
1007
	'hidden',
1008
	$if
1009
));
1010

    
1011
print($form);
1012

    
1013
?>
1014
<div class="infoblock blockopen">
1015
<?php
1016
print_info_box(
1017
	sprintf(
1018
		gettext('The DNS servers entered in %1$sSystem: General Setup%3$s (or the %2$sDNS forwarder%3$s if enabled) will be assigned to clients by the DHCP server.'),
1019
		'<a href="system.php">',
1020
		'<a href="services_dnsmasq.php"/>',
1021
		'</a>') .
1022
	'<br />' .
1023
	sprintf(
1024
		gettext('The DHCP lease table can be viewed on the %1$sStatus: DHCPv6 leases%2$s page.'),
1025
		'<a href="status_dhcpv6_leases.php">',
1026
		'</a>'),
1027
	'info',
1028
	false);
1029
?>
1030
</div>
1031
<div class="panel panel-default">
1032
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCPv6 Static Mappings for this Interface");?></h2></div>
1033
	<div class="panel-body table-responsive">
1034
		<table class="table table-striped table-hover table-condensed">
1035
			<thead>
1036
				<tr>
1037
					<th><?=gettext("DUID")?></th>
1038
					<th><?=gettext("IPv6 address")?></th>
1039
					<th><?=gettext("Hostname")?></th>
1040
					<th><?=gettext("Description")?></th>
1041
					<th><!-- Buttons --></th>
1042
				</tr>
1043
			</thead>
1044
			<tbody>
1045
<?php
1046
if (is_array($a_maps)):
1047
	$i = 0;
1048
	foreach ($a_maps as $mapent):
1049
		if ($mapent['duid'] != "" or $mapent['ipaddrv6'] != ""):
1050
?>
1051
				<tr>
1052
					<td>
1053
						<?=htmlspecialchars($mapent['duid'])?>
1054
					</td>
1055
					<td>
1056
						<?=htmlspecialchars($mapent['ipaddrv6'])?>
1057
					</td>
1058
					<td>
1059
						<?=htmlspecialchars($mapent['hostname'])?>
1060
					</td>
1061
					<td>
1062
						<?=htmlspecialchars($mapent['descr'])?>
1063
					</td>
1064
					<td>
1065
						<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>" href="services_dhcpv6_edit.php?if=<?=$if?>&amp;id=<?=$i?>"></a>
1066
						<a class="fa fa-trash"	title="<?=gettext('Delete static mapping')?>" href="services_dhcpv6.php?if=<?=$if?>&amp;act=del&amp;id=<?=$i?>" usepost></a>
1067
					</td>
1068
				</tr>
1069
<?php
1070
		endif;
1071
	$i++;
1072
	endforeach;
1073
endif;
1074
?>
1075
			</tbody>
1076
		</table>
1077
	</div>
1078
</div>
1079

    
1080
<nav class="action-buttons">
1081
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1082
		<i class="fa fa-plus icon-embed-btn"></i>
1083
		<?=gettext("Add")?>
1084
	</a>
1085
</nav>
1086

    
1087
<script type="text/javascript">
1088
//<![CDATA[
1089
events.push(function() {
1090

    
1091
	// Show advanced DNS options ======================================================================================
1092
	var showadvdns = false;
1093

    
1094
	function show_advdns(ispageload) {
1095
		var text;
1096
		// On page load decide the initial state based on the data.
1097
		if (ispageload) {
1098
<?php
1099
			if (!$pconfig['ddnsupdate'] &&
1100
			    !$pconfig['ddnsforcehostname'] &&
1101
			    empty($pconfig['ddnsdomain']) &&
1102
			    empty($pconfig['ddnsdomainprimary']) &&
1103
			    empty($pconfig['ddnsdomainkeyname']) &&
1104
			    (empty($pconfig['ddnsdomainkeyalgorithm'])  || ($pconfig['ddnsdomainkeyalgorithm'] == "hmac-md5")) &&
1105
			    empty($pconfig['ddnsdomainkey']) &&
1106
			    (empty($pconfig['ddnsclientupdates']) || ($pconfig['ddnsclientupdates'] == "allow")) &&
1107
			    !$pconfig['ddnsreverse']) {
1108
				$showadv = false;
1109
			} else {
1110
				$showadv = true;
1111
			}
1112
?>
1113
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1114
		} else {
1115
			// It was a click, swap the state.
1116
			showadvdns = !showadvdns;
1117
		}
1118

    
1119
		hideCheckbox('ddnsupdate', !showadvdns);
1120
		hideInput('ddnsdomain', !showadvdns);
1121
		hideCheckbox('ddnsforcehostname', !showadvdns);
1122
		hideInput('ddnsdomainprimary', !showadvdns);
1123
		hideInput('ddnsdomainkeyname', !showadvdns);
1124
		hideInput('ddnsdomainkeyalgorithm', !showadvdns);
1125
		hideInput('ddnsdomainkey', !showadvdns);
1126
		hideInput('ddnsclientupdates', !showadvdns);
1127
		hideCheckbox('ddnsreverse', !showadvdns);
1128

    
1129
		if (showadvdns) {
1130
			text = "<?=gettext('Hide Advanced');?>";
1131
		} else {
1132
			text = "<?=gettext('Display Advanced');?>";
1133
		}
1134
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1135
	}
1136

    
1137
	$('#btnadvdns').click(function(event) {
1138
		show_advdns();
1139
	});
1140

    
1141
	// Show advanced NTP options ======================================================================================
1142
	var showadvntp = false;
1143

    
1144
	function show_advntp(ispageload) {
1145
		var text;
1146
		// On page load decide the initial state based on the data.
1147
		if (ispageload) {
1148
<?php
1149
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1150
				$showadv = false;
1151
			} else {
1152
				$showadv = true;
1153
			}
1154
?>
1155
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1156
		} else {
1157
			// It was a click, swap the state.
1158
			showadvntp = !showadvntp;
1159
		}
1160

    
1161
		hideInput('ntp1', !showadvntp);
1162
		hideInput('ntp2', !showadvntp);
1163

    
1164
		if (showadvntp) {
1165
			text = "<?=gettext('Hide Advanced');?>";
1166
		} else {
1167
			text = "<?=gettext('Display Advanced');?>";
1168
		}
1169
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1170
	}
1171

    
1172
	$('#btnadvntp').click(function(event) {
1173
		show_advntp();
1174
	});
1175

    
1176
	// Show advanced LDAP options ======================================================================================
1177
	var showadvldap = false;
1178

    
1179
	function show_advldap(ispageload) {
1180
		var text;
1181
		// On page load decide the initial state based on the data.
1182
		if (ispageload) {
1183
<?php
1184
			if (empty($pconfig['ldap'])) {
1185
				$showadv = false;
1186
			} else {
1187
				$showadv = true;
1188
			}
1189
?>
1190
			showadvldap = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1191
		} else {
1192
			// It was a click, swap the state.
1193
			showadvldap = !showadvldap;
1194
		}
1195

    
1196
		hideInput('ldap', !showadvldap);
1197

    
1198
		if (showadvldap) {
1199
			text = "<?=gettext('Hide Advanced');?>";
1200
		} else {
1201
			text = "<?=gettext('Display Advanced');?>";
1202
		}
1203
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1204
	}
1205

    
1206
	$('#btnadvldap').click(function(event) {
1207
		show_advldap();
1208
	});
1209

    
1210
	// Show advanced Netboot options ======================================================================================
1211
	var showadvnetboot = false;
1212

    
1213
	function show_advnetboot(ispageload) {
1214
		var text;
1215
		// On page load decide the initial state based on the data.
1216
		if (ispageload) {
1217
<?php
1218
			if (!$pconfig['netboot'] && empty($pconfig['bootfile_url'])) {
1219
				$showadv = false;
1220
			} else {
1221
				$showadv = true;
1222
			}
1223
?>
1224
			showadvnetboot = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1225
		} else {
1226
			// It was a click, swap the state.
1227
			showadvnetboot = !showadvnetboot;
1228
		}
1229

    
1230
		hideCheckbox('netboot', !showadvnetboot);
1231
		hideInput('bootfile_url', !showadvnetboot);
1232

    
1233
		if (showadvnetboot) {
1234
			text = "<?=gettext('Hide Advanced');?>";
1235
		} else {
1236
			text = "<?=gettext('Display Advanced');?>";
1237
		}
1238
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1239
	}
1240

    
1241
	$('#btnadvnetboot').click(function(event) {
1242
		show_advnetboot();
1243
	});
1244

    
1245
	// Show advanced additional opts options ===========================================================================
1246
	var showadvopts = false;
1247

    
1248
	function show_advopts(ispageload) {
1249
		var text;
1250
		// On page load decide the initial state based on the data.
1251
		if (ispageload) {
1252
<?php
1253
			if (empty($pconfig['numberoptions']) ||
1254
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1255
				$showadv = false;
1256
			} else {
1257
				$showadv = true;
1258
			}
1259
?>
1260
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1261
		} else {
1262
			// It was a click, swap the state.
1263
			showadvopts = !showadvopts;
1264
		}
1265

    
1266
		hideClass('adnloptions', !showadvopts);
1267
		hideInput('addrow', !showadvopts);
1268

    
1269
		if (showadvopts) {
1270
			text = "<?=gettext('Hide Advanced');?>";
1271
		} else {
1272
			text = "<?=gettext('Display Advanced');?>";
1273
		}
1274
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1275
	}
1276

    
1277
	$('#btnadvopts').click(function(event) {
1278
		show_advopts();
1279
		checkLastRow();
1280
	});
1281

    
1282
	// On initial load
1283
	show_advdns(true);
1284
	show_advntp(true);
1285
	show_advldap(true);
1286
	show_advnetboot(true);
1287
	show_advopts(true);
1288
	if ($('#enable').prop('checked')) {
1289
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1290
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1291
	} else {
1292
		hideClass('adnloptions', true);
1293
		hideInput('addrow', true);
1294
	}
1295

    
1296
});
1297
//]]>
1298
</script>
1299

    
1300
<?php include('foot.inc');
(121-121/227)