Project

General

Profile

Download (39.1 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-2020 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['dhcp6c-dns'] = ($config['dhcpdv6'][$if]['dhcp6c-dns'] != 'disabled') ? "enabled" : "disabled";
145
	$pconfig['enable'] = isset($config['dhcpdv6'][$if]['enable']);
146
	$pconfig['ddnsdomain'] = $config['dhcpdv6'][$if]['ddnsdomain'];
147
	$pconfig['ddnsdomainprimary'] = $config['dhcpdv6'][$if]['ddnsdomainprimary'];
148
	$pconfig['ddnsdomainkeyname'] = $config['dhcpdv6'][$if]['ddnsdomainkeyname'];
149
	$pconfig['ddnsdomainkeyalgorithm'] = $config['dhcpdv6'][$if]['ddnsdomainkeyalgorithm'];
150
	$pconfig['ddnsdomainkey'] = $config['dhcpdv6'][$if]['ddnsdomainkey'];
151
	$pconfig['ddnsupdate'] = isset($config['dhcpdv6'][$if]['ddnsupdate']);
152
	$pconfig['ddnsforcehostname'] = isset($config['dhcpdv6'][$if]['ddnsforcehostname']);
153
	$pconfig['ddnsreverse'] = isset($config['dhcpdv6'][$if]['ddnsreverse']);
154
	$pconfig['ddnsclientupdates'] = $config['dhcpdv6'][$if]['ddnsclientupdates'];
155
	list($pconfig['ntp1'], $pconfig['ntp2'], $pconfig['ntp3'] ) = $config['dhcpdv6'][$if]['ntpserver'];
156
	$pconfig['tftp'] = $config['dhcpdv6'][$if]['tftp'];
157
	$pconfig['ldap'] = $config['dhcpdv6'][$if]['ldap'];
158
	$pconfig['netboot'] = isset($config['dhcpdv6'][$if]['netboot']);
159
	$pconfig['bootfile_url'] = $config['dhcpdv6'][$if]['bootfile_url'];
160
	$pconfig['netmask'] = $config['dhcpdv6'][$if]['netmask'];
161
	$pconfig['numberoptions'] = $config['dhcpdv6'][$if]['numberoptions'];
162
	$pconfig['dhcpv6leaseinlocaltime'] = $config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'];
163
	if (!is_array($config['dhcpdv6'][$if]['staticmap'])) {
164
		$config['dhcpdv6'][$if]['staticmap'] = array();
165
	}
166
	init_config_arr(array('dhcpdv6', $if, 'staticmap'));
167
	$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
168
}
169

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

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

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

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

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

    
193
	foreach ($dhcrelayifs as $dhcrelayif) {
194

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

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

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

    
212
	$pconfig = $_POST;
213

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

    
226
	/* input validation */
227

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

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

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

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

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

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

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

    
268
	$range_from_to_ok = true;
269

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

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

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

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

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

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

    
372
	// 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.
373
	if (!$input_errors && $_POST['range_from'] && $_POST['range_to']) {
374
		/* make sure the range lies within the current subnet */
375
		$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
376
		$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
377

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

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

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

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

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

    
432
		unset($config['dhcpdv6'][$if]['winsserver']);
433

    
434
		unset($config['dhcpdv6'][$if]['dnsserver']);
435
		if ($_POST['dns1']) {
436
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
437
		}
438
		if ($_POST['dns2']) {
439
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
440
		}
441
		if ($_POST['dns3']) {
442
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
443
		}
444
		if ($_POST['dns4']) {
445
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
446
		}
447
		$config['dhcpdv6'][$if]['dhcp6c-dns'] = ($_POST['dhcp6c-dns']) ? "enabled" : "disabled";
448
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
449
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
450
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
451
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
452
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
453
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
454
		$config['dhcpdv6'][$if]['ddnsdomainkeyalgorithm'] = $_POST['ddnsdomainkeyalgorithm'];
455
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
456
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
457
		$config['dhcpdv6'][$if]['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
458
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
459
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
460

    
461
		unset($config['dhcpdv6'][$if]['ntpserver']);
462
		if ($_POST['ntp1']) {
463
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
464
		}
465
		if ($_POST['ntp2']) {
466
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
467
		}
468
		if ($_POST['ntp3']) {
469
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp3'];
470
		}
471

    
472
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
473
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
474
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
475
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
476
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
477

    
478
		// Handle the custom options rowhelper
479
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
480
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
481
		}
482

    
483
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
484

    
485
		write_config();
486

    
487
		$changes_applied = true;
488
		$retval = dhcpv6_apply_changes($dhcpdv6_enable_changed);
489
	}
490
}
491

    
492
if ($_POST['act'] == "del") {
493
	if ($a_maps[$_POST['id']]) {
494
		unset($a_maps[$_POST['id']]);
495
		write_config();
496
		if (isset($config['dhcpdv6'][$if]['enable'])) {
497
			mark_subsystem_dirty('staticmapsv6');
498
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstaticv6'])) {
499
				mark_subsystem_dirty('hosts');
500
			}
501
		}
502
		header("Location: services_dhcpv6.php?if={$if}");
503
		exit;
504
	}
505
}
506

    
507
$pgtitle = array(gettext("Services"), htmlspecialchars(gettext("DHCPv6 Server & RA")));
508
$pglinks = array("", "services_dhcpv6.php");
509

    
510
if (!empty($if) && isset($iflist[$if])) {
511
	$pgtitle[] = $iflist[$if];
512
	$pglinks[] = "@self";
513
	$pgtitle[] = gettext("DHCPv6 Server");
514
	$pglinks[] = "@self";
515
}
516
$shortcut_section = "dhcp6";
517

    
518
include("head.inc");
519

    
520
if ($input_errors) {
521
	print_input_errors($input_errors);
522
}
523

    
524
if ($changes_applied) {
525
	print_apply_result_box($retval);
526
}
527

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

    
532
/* active tabs */
533
$tab_array = array();
534
$tabscounter = 0;
535
$i = 0;
536

    
537
foreach ($iflist as $ifent => $ifname) {
538
	$oc = $config['interfaces'][$ifent];
539
	$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
540
	    (is_ipaddrv6($oc['ipaddrv6']) &&
541
	    !is_linklocal($oc['ipaddrv6'])));
542

    
543
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
544
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
545
	    !$valid_if_ipaddrv6) {
546
		continue;
547
	}
548

    
549
	if ($ifent == $if) {
550
		$active = true;
551
	} else {
552
		$active = false;
553
	}
554

    
555
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
556
	$tabscounter++;
557
}
558

    
559
/* tack on PPPoE or PPtP servers here */
560
/* pppoe server */
561
if (is_array($config['pppoes']['pppoe'])) {
562
	foreach ($config['pppoes']['pppoe'] as $pppoe) {
563
		if ($pppoe['mode'] == "server") {
564
			$ifent = "poes". $pppoe['pppoeid'];
565
			$ifname = strtoupper($ifent);
566

    
567
			if ($ifent == $if) {
568
				$active = true;
569
			} else {
570
				$active = false;
571
			}
572

    
573
			$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
574
			$tabscounter++;
575
		}
576
	}
577
}
578

    
579
if ($tabscounter == 0) {
580
	print_info_box(gettext("The DHCPv6 Server can only be enabled on interfaces configured with a static IPv6 address. This system has none."), 'danger');
581
	include("foot.inc");
582
	exit;
583
}
584

    
585
display_top_tabs($tab_array);
586

    
587
$tab_array = array();
588
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
589
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
590
display_top_tabs($tab_array, false, 'nav nav-tabs');
591

    
592
$form = new Form();
593

    
594
$section = new Form_Section('DHCPv6 Options');
595

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

    
612
if (is_ipaddrv6($ifcfgip)) {
613

    
614
	if ($ifcfgip == "::") {
615
		$sntext = "Prefix Delegation";
616
	} else {
617
		$sntext = gen_subnetv6($ifcfgip, $ifcfgsn);
618
	}
619
	$section->addInput(new Form_StaticText(
620
		'Subnet',
621
		$sntext
622
		));
623

    
624
	$section->addInput(new Form_StaticText(
625
		'Subnet Mask',
626
		$ifcfgsn . ' bits'
627
		));
628

    
629
	$section->addInput(new Form_StaticText(
630
		'Available Range',
631
		$range_from = gen_subnetv6($ifcfgip, $ifcfgsn) . ' to ' . gen_subnetv6_max($ifcfgip, $ifcfgsn)
632
		))->setHelp($trackifname ? 'Prefix Delegation subnet will be appended to the beginning of the defined range':'');
633
}
634

    
635
$f1 = new Form_Input(
636
	'range_from',
637
	null,
638
	'text',
639
	$pconfig['range_from']
640
);
641

    
642
$f1->setHelp('From');
643

    
644
$f2 = new Form_Input(
645
	'range_to',
646
	null,
647
	'text',
648
	$pconfig['range_to']
649
);
650

    
651
$f2->setHelp('To');
652

    
653
$group = new Form_Group('*Range');
654

    
655
$group->add($f1);
656
$group->add($f2);
657

    
658
$section->add($group);
659

    
660
$f1 = new Form_Input(
661
	'prefixrange_from',
662
	null,
663
	'text',
664
	$pconfig['prefixrange_from']
665
);
666

    
667
$f1->setHelp('From');
668

    
669
$f2 = new Form_Input(
670
	'prefixrange_to',
671
	null,
672
	'text',
673
	$pconfig['prefixrange_to']
674
);
675

    
676
$f2->setHelp('To');
677

    
678
$group = new Form_Group('Prefix Delegation Range');
679

    
680
$group->add($f1);
681
$group->add($f2);
682

    
683
$section->add($group);
684

    
685
$section->addInput(new Form_Select(
686
	'prefixrange_length',
687
	'Prefix Delegation Size',
688
	$pconfig['prefixrange_length'],
689
	array(
690
		'48' => '48',
691
		'52' => '52',
692
		'56' => '56',
693
		'59' => '59',
694
		'60' => '60',
695
		'61' => '61',
696
		'62' => '62',
697
		'63' => '63',
698
		'64' => '64'
699
		)
700
))->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.');
701

    
702
$group = new Form_Group('DNS Servers');
703

    
704
for ($i=1;$i<=4; $i++) {
705
	$group->add(new Form_input(
706
		'dns' . $i,
707
		null,
708
		'text',
709
		$pconfig['dns' . $i],
710
		['placeholder' => 'DNS ' . $i]
711
	));
712
}
713

    
714
$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.');
715
$section->add($group);
716

    
717
$section->addInput(new Form_Checkbox(
718
	'dhcp6c-dns',
719
	null,
720
	'Provide DNS servers to DHCPv6 clients',
721
	($pconfig['dhcp6c-dns'] == "enabled")
722
))->setHelp('Unchecking this box disables the dhcp6.name-servers option. ' .
723
			'Use with caution, as the resulting behavior may violate RFCs and lead to unintended client behavior.');
724

    
725
$section->addInput(new Form_Input(
726
	'domain',
727
	'Domain name',
728
	'text',
729
	$pconfig['domain']
730
))->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. ');
731

    
732
$section->addInput(new Form_Input(
733
	'domainsearchlist',
734
	'Domain search list',
735
	'text',
736
	$pconfig['domainsearchlist']
737
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
738

    
739
$section->addInput(new Form_Input(
740
	'deftime',
741
	'Default lease time',
742
	'text',
743
	$pconfig['deftime']
744
))->setHelp('Lease time in seconds. Used for clients that do not ask for a specific expiration time. %1$s' .
745
			'The default is 7200 seconds.', '<br />');
746

    
747
$section->addInput(new Form_Input(
748
	'maxtime',
749
	'Max lease time',
750
	'text',
751
	$pconfig['maxtime']
752
))->setHelp('Maximum lease time for clients that ask for a specific expiration time. %1$s' .
753
			'The default is 86400 seconds.', '<br />');
754

    
755
$section->addInput(new Form_Checkbox(
756
	'dhcpv6leaseinlocaltime',
757
	'Time Format Change',
758
	'Change DHCPv6 display lease time from UTC to local time',
759
	$pconfig['dhcpv6leaseinlocaltime']
760
))->setHelp('By default DHCPv6 leases are displayed in UTC time. ' .
761
			'By checking this box DHCPv6 lease time will be displayed in local time and set to time zone selected. ' .
762
			'This will be used for all DHCPv6 interfaces lease time.');
763

    
764
$btnadv = new Form_Button(
765
	'btnadvdns',
766
	'Display Advanced',
767
	null,
768
	'fa-cog'
769
);
770

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

    
773
$section->addInput(new Form_StaticText(
774
	'Dynamic DNS',
775
	$btnadv
776
));
777

    
778
$section->addInput(new Form_Checkbox(
779
	'ddnsupdate',
780
	'DHCP Registration',
781
	'Enable registration of DHCP client names in DNS.',
782
	$pconfig['ddnsupdate']
783
));
784

    
785
$section->addInput(new Form_Input(
786
	'ddnsdomain',
787
	'DDNS Domain',
788
	'text',
789
	$pconfig['ddnsdomain']
790
))->setHelp('Enter the dynamic DNS domain which will be used to register client names in the DNS server.');
791

    
792
$section->addInput(new Form_Checkbox(
793
	'ddnsforcehostname',
794
	'DDNS Hostnames',
795
	'Force dynamic DNS hostname to be the same as configured hostname for Static Mappings',
796
	$pconfig['ddnsforcehostname']
797
))->setHelp('Default registers host name option supplied by DHCP client.');
798

    
799
$section->addInput(new Form_IpAddress(
800
	'ddnsdomainprimary',
801
	'DDNS Server IP',
802
	$pconfig['ddnsdomainprimary'],
803
	'V4'
804
))->setHelp('Enter the primary domain name server IPv4 address for the dynamic domain name.');
805

    
806
$section->addInput(new Form_Input(
807
	'ddnsdomainkeyname',
808
	'DDNS Domain Key name',
809
	'text',
810
	$pconfig['ddnsdomainkeyname']
811
))->setHelp('Enter the dynamic DNS domain key name which will be used to register client names in the DNS server.');
812

    
813
$section->addInput(new Form_Select(
814
	'ddnsdomainkeyalgorithm',
815
	'Key algorithm',
816
	$pconfig['ddnsdomainkeyalgorithm'],
817
	array(
818
		'hmac-md5' => 'HMAC-MD5 (legacy default)',
819
		'hmac-sha1' => 'HMAC-SHA1',
820
		'hmac-sha224' => 'HMAC-SHA224',
821
		'hmac-sha256' => 'HMAC-SHA256 (current bind9 default)',
822
		'hmac-sha384' => 'HMAC-SHA384',
823
		'hmac-sha512' => 'HMAC-SHA512 (most secure)',
824
	)
825
));
826

    
827
$section->addInput(new Form_Input(
828
	'ddnsdomainkey',
829
	'DDNS Domain Key secret',
830
	'text',
831
	$pconfig['ddnsdomainkey']
832
))->setHelp('Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.');
833

    
834
$section->addInput(new Form_Select(
835
	'ddnsclientupdates',
836
	'DDNS Client Updates',
837
	$pconfig['ddnsclientupdates'],
838
	array(
839
	    'allow' => gettext('Allow'),
840
	    'deny' => gettext('Deny'),
841
	    'ignore' => gettext('Ignore'))
842
))->setHelp('How Forward entries are handled when client indicates they wish to update DNS.  ' .
843
	    'Allow prevents DHCP from updating Forward entries, Deny indicates that DHCP will ' .
844
	    'do the updates and the client should not, Ignore specifies that DHCP will do the ' .
845
	    'update and the client can also attempt the update usually using a different domain name.');
846

    
847
$section->addInput(new Form_Checkbox(
848
	'ddnsreverse',
849
	'DDNS Reverse',
850
	'Add reverse dynamic DNS entries.',
851
	$pconfig['ddnsreverse']
852
));
853

    
854
$btnadv = new Form_Button(
855
	'btnadvntp',
856
	'Display Advanced',
857
	null,
858
	'fa-cog'
859
);
860

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

    
863
$section->addInput(new Form_StaticText(
864
	'NTP servers',
865
	$btnadv
866
));
867

    
868
$group = new Form_Group('NTP Servers');
869

    
870
$group->add(new Form_Input(
871
	'ntp1',
872
	'NTP Server 1',
873
	'text',
874
	$pconfig['ntp1'],
875
	['placeholder' => 'NTP 1']
876
));
877

    
878
$group->add(new Form_Input(
879
	'ntp2',
880
	'NTP Server 2',
881
	'text',
882
	$pconfig['ntp2'],
883
	['placeholder' => 'NTP 2']
884
));
885

    
886
$group->add(new Form_Input(
887
	'ntp3',
888
	'NTP Server 3',
889
	'text',
890
	$pconfig['ntp3'],
891
	['placeholder' => 'NTP 3']
892
));
893

    
894
$group->addClass('ntpclass');
895

    
896
$section->add($group);
897

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

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

    
907
$section->addInput(new Form_StaticText(
908
	'LDAP',
909
	$btnadv
910
));
911

    
912
$section->addInput(new Form_Input(
913
	'ldap',
914
	'LDAP URI',
915
	'text',
916
	$pconfig['ldap']
917
));
918

    
919
$btnadv = new Form_Button(
920
	'btnadvnetboot',
921
	'Display Advanced',
922
	null,
923
	'fa-cog'
924
);
925

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

    
928
$section->addInput(new Form_StaticText(
929
	'Network booting',
930
	$btnadv
931
));
932

    
933
$section->addInput(new Form_Checkbox(
934
	'netboot',
935
	'Network booting',
936
	'Enable Network Booting',
937
	$pconfig['netboot']
938
));
939

    
940
$section->addInput(new Form_Input(
941
	'bootfile_url',
942
	'Bootfile URL',
943
	'text',
944
	$pconfig['bootfile_url']
945
));
946

    
947
$btnadv = new Form_Button(
948
	'btnadvopts',
949
	'Display Advanced',
950
	null,
951
	'fa-cog'
952
);
953

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

    
956
$section->addInput(new Form_StaticText(
957
	'Additional BOOTP/DHCP Options',
958
	$btnadv
959
));
960

    
961
$form->add($section);
962

    
963
$title = 'Show Additional BOOTP/DHCP Options';
964

    
965
if (!$pconfig['numberoptions']) {
966
	$noopts = true;
967
	$pconfig['numberoptions'] = array();
968
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
969
} else {
970
	$noopts = false;
971
}
972

    
973
$counter = 0;
974
if (!is_array($pconfig['numberoptions'])) {
975
	$pconfig['numberoptions'] = array();
976
}
977
if (!is_array($pconfig['numberoptions']['item'])) {
978
	$pconfig['numberoptions']['item'] = array();
979
}
980
$last = count($pconfig['numberoptions']['item']) - 1;
981

    
982
foreach ($pconfig['numberoptions']['item'] as $item) {
983
	$group = new Form_Group(null);
984
	$group->addClass('repeatable');
985
	$group->addClass('adnloptions');
986

    
987
	$group->add(new Form_Input(
988
		'number' . $counter,
989
		null,
990
		'text',
991
		$item['number']
992
	))->setHelp($counter == $last ? 'Number':null);
993

    
994
	$group->add(new Form_Input(
995
		'value' . $counter,
996
		null,
997
		'text',
998
		base64_decode($item['value'])
999
	))->setHelp($counter == $last ? 'Value':null);
1000

    
1001
	$btn = new Form_Button(
1002
		'deleterow' . $counter,
1003
		'Delete',
1004
		null,
1005
		'fa-trash'
1006
	);
1007

    
1008
	$btn->addClass('btn-warning');
1009
	$group->add($btn);
1010
	$section->add($group);
1011
	$counter++;
1012
}
1013

    
1014

    
1015
$btnaddopt = new Form_Button(
1016
	'addrow',
1017
	'Add Option',
1018
	null,
1019
	'fa-plus'
1020
);
1021

    
1022
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
1023

    
1024
$section->addInput($btnaddopt);
1025

    
1026
$form->addGlobal(new Form_Input(
1027
	'if',
1028
	null,
1029
	'hidden',
1030
	$if
1031
));
1032

    
1033
print($form);
1034

    
1035
?>
1036
<div class="infoblock blockopen">
1037
<?php
1038
print_info_box(
1039
	sprintf(
1040
		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.'),
1041
		'<a href="system.php">',
1042
		'<a href="services_dnsmasq.php"/>',
1043
		'</a>') .
1044
	'<br />' .
1045
	sprintf(
1046
		gettext('The DHCP lease table can be viewed on the %1$sStatus: DHCPv6 leases%2$s page.'),
1047
		'<a href="status_dhcpv6_leases.php">',
1048
		'</a>'),
1049
	'info',
1050
	false);
1051
?>
1052
</div>
1053
<div class="panel panel-default">
1054
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCPv6 Static Mappings for this Interface");?></h2></div>
1055
	<div class="panel-body table-responsive">
1056
		<table class="table table-striped table-hover table-condensed">
1057
			<thead>
1058
				<tr>
1059
					<th><?=gettext("DUID")?></th>
1060
					<th><?=gettext("IPv6 address")?></th>
1061
					<th><?=gettext("Hostname")?></th>
1062
					<th><?=gettext("Description")?></th>
1063
					<th><!-- Buttons --></th>
1064
				</tr>
1065
			</thead>
1066
			<tbody>
1067
<?php
1068
if (is_array($a_maps)):
1069
	$i = 0;
1070
	foreach ($a_maps as $mapent):
1071
		if ($mapent['duid'] != "" or $mapent['ipaddrv6'] != ""):
1072
?>
1073
				<tr>
1074
					<td>
1075
						<?=htmlspecialchars($mapent['duid'])?>
1076
					</td>
1077
					<td>
1078
						<?=htmlspecialchars($mapent['ipaddrv6'])?>
1079
					</td>
1080
					<td>
1081
						<?=htmlspecialchars($mapent['hostname'])?>
1082
					</td>
1083
					<td>
1084
						<?=htmlspecialchars($mapent['descr'])?>
1085
					</td>
1086
					<td>
1087
						<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>" href="services_dhcpv6_edit.php?if=<?=$if?>&amp;id=<?=$i?>"></a>
1088
						<a class="fa fa-trash"	title="<?=gettext('Delete static mapping')?>" href="services_dhcpv6.php?if=<?=$if?>&amp;act=del&amp;id=<?=$i?>" usepost></a>
1089
					</td>
1090
				</tr>
1091
<?php
1092
		endif;
1093
	$i++;
1094
	endforeach;
1095
endif;
1096
?>
1097
			</tbody>
1098
		</table>
1099
	</div>
1100
</div>
1101

    
1102
<nav class="action-buttons">
1103
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1104
		<i class="fa fa-plus icon-embed-btn"></i>
1105
		<?=gettext("Add")?>
1106
	</a>
1107
</nav>
1108

    
1109
<script type="text/javascript">
1110
//<![CDATA[
1111
events.push(function() {
1112

    
1113
	// Show advanced DNS options ======================================================================================
1114
	var showadvdns = false;
1115

    
1116
	function show_advdns(ispageload) {
1117
		var text;
1118
		// On page load decide the initial state based on the data.
1119
		if (ispageload) {
1120
<?php
1121
			if (!$pconfig['ddnsupdate'] &&
1122
			    !$pconfig['ddnsforcehostname'] &&
1123
			    empty($pconfig['ddnsdomain']) &&
1124
			    empty($pconfig['ddnsdomainprimary']) &&
1125
			    empty($pconfig['ddnsdomainkeyname']) &&
1126
			    (empty($pconfig['ddnsdomainkeyalgorithm'])  || ($pconfig['ddnsdomainkeyalgorithm'] == "hmac-md5")) &&
1127
			    empty($pconfig['ddnsdomainkey']) &&
1128
			    (empty($pconfig['ddnsclientupdates']) || ($pconfig['ddnsclientupdates'] == "allow")) &&
1129
			    !$pconfig['ddnsreverse']) {
1130
				$showadv = false;
1131
			} else {
1132
				$showadv = true;
1133
			}
1134
?>
1135
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1136
		} else {
1137
			// It was a click, swap the state.
1138
			showadvdns = !showadvdns;
1139
		}
1140

    
1141
		hideCheckbox('ddnsupdate', !showadvdns);
1142
		hideInput('ddnsdomain', !showadvdns);
1143
		hideCheckbox('ddnsforcehostname', !showadvdns);
1144
		hideInput('ddnsdomainprimary', !showadvdns);
1145
		hideInput('ddnsdomainkeyname', !showadvdns);
1146
		hideInput('ddnsdomainkeyalgorithm', !showadvdns);
1147
		hideInput('ddnsdomainkey', !showadvdns);
1148
		hideInput('ddnsclientupdates', !showadvdns);
1149
		hideCheckbox('ddnsreverse', !showadvdns);
1150

    
1151
		if (showadvdns) {
1152
			text = "<?=gettext('Hide Advanced');?>";
1153
		} else {
1154
			text = "<?=gettext('Display Advanced');?>";
1155
		}
1156
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1157
	}
1158

    
1159
	$('#btnadvdns').click(function(event) {
1160
		show_advdns();
1161
	});
1162

    
1163
	// Show advanced NTP options ======================================================================================
1164
	var showadvntp = false;
1165

    
1166
	function show_advntp(ispageload) {
1167
		var text;
1168
		// On page load decide the initial state based on the data.
1169
		if (ispageload) {
1170
<?php
1171
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2']) && empty($pconfig['ntp3'])) {
1172
				$showadv = false;
1173
			} else {
1174
				$showadv = true;
1175
			}
1176
?>
1177
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1178
		} else {
1179
			// It was a click, swap the state.
1180
			showadvntp = !showadvntp;
1181
		}
1182

    
1183
		hideInput('ntp1', !showadvntp);
1184
		hideInput('ntp2', !showadvntp);
1185
		hideInput('ntp3', !showadvntp);
1186

    
1187
		if (showadvntp) {
1188
			text = "<?=gettext('Hide Advanced');?>";
1189
		} else {
1190
			text = "<?=gettext('Display Advanced');?>";
1191
		}
1192
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1193
	}
1194

    
1195
	$('#btnadvntp').click(function(event) {
1196
		show_advntp();
1197
	});
1198

    
1199
	// Show advanced LDAP options ======================================================================================
1200
	var showadvldap = false;
1201

    
1202
	function show_advldap(ispageload) {
1203
		var text;
1204
		// On page load decide the initial state based on the data.
1205
		if (ispageload) {
1206
<?php
1207
			if (empty($pconfig['ldap'])) {
1208
				$showadv = false;
1209
			} else {
1210
				$showadv = true;
1211
			}
1212
?>
1213
			showadvldap = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1214
		} else {
1215
			// It was a click, swap the state.
1216
			showadvldap = !showadvldap;
1217
		}
1218

    
1219
		hideInput('ldap', !showadvldap);
1220

    
1221
		if (showadvldap) {
1222
			text = "<?=gettext('Hide Advanced');?>";
1223
		} else {
1224
			text = "<?=gettext('Display Advanced');?>";
1225
		}
1226
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1227
	}
1228

    
1229
	$('#btnadvldap').click(function(event) {
1230
		show_advldap();
1231
	});
1232

    
1233
	// Show advanced Netboot options ======================================================================================
1234
	var showadvnetboot = false;
1235

    
1236
	function show_advnetboot(ispageload) {
1237
		var text;
1238
		// On page load decide the initial state based on the data.
1239
		if (ispageload) {
1240
<?php
1241
			if (!$pconfig['netboot'] && empty($pconfig['bootfile_url'])) {
1242
				$showadv = false;
1243
			} else {
1244
				$showadv = true;
1245
			}
1246
?>
1247
			showadvnetboot = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1248
		} else {
1249
			// It was a click, swap the state.
1250
			showadvnetboot = !showadvnetboot;
1251
		}
1252

    
1253
		hideCheckbox('netboot', !showadvnetboot);
1254
		hideInput('bootfile_url', !showadvnetboot);
1255

    
1256
		if (showadvnetboot) {
1257
			text = "<?=gettext('Hide Advanced');?>";
1258
		} else {
1259
			text = "<?=gettext('Display Advanced');?>";
1260
		}
1261
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1262
	}
1263

    
1264
	$('#btnadvnetboot').click(function(event) {
1265
		show_advnetboot();
1266
	});
1267

    
1268
	// Show advanced additional opts options ===========================================================================
1269
	var showadvopts = false;
1270

    
1271
	function show_advopts(ispageload) {
1272
		var text;
1273
		// On page load decide the initial state based on the data.
1274
		if (ispageload) {
1275
<?php
1276
			if (empty($pconfig['numberoptions']) ||
1277
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1278
				$showadv = false;
1279
			} else {
1280
				$showadv = true;
1281
			}
1282
?>
1283
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1284
		} else {
1285
			// It was a click, swap the state.
1286
			showadvopts = !showadvopts;
1287
		}
1288

    
1289
		hideClass('adnloptions', !showadvopts);
1290
		hideInput('addrow', !showadvopts);
1291

    
1292
		if (showadvopts) {
1293
			text = "<?=gettext('Hide Advanced');?>";
1294
		} else {
1295
			text = "<?=gettext('Display Advanced');?>";
1296
		}
1297
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1298
	}
1299

    
1300
	$('#btnadvopts').click(function(event) {
1301
		show_advopts();
1302
		checkLastRow();
1303
	});
1304

    
1305
	// On initial load
1306
	show_advdns(true);
1307
	show_advntp(true);
1308
	show_advldap(true);
1309
	show_advnetboot(true);
1310
	show_advopts(true);
1311
	if ($('#enable').prop('checked')) {
1312
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1313
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1314
	} else {
1315
		hideClass('adnloptions', true);
1316
		hideInput('addrow', true);
1317
	}
1318

    
1319
});
1320
//]]>
1321
</script>
1322

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