Project

General

Profile

Download (38.5 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-2018 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2010 Seth Mos <seth.mos@dds.nl>
8
 * All rights reserved.
9
 *
10
 * originally based on m0n0wall (http://m0n0.ch/wall)
11
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
 * All rights reserved.
13
 *
14
 * Licensed under the Apache License, Version 2.0 (the "License");
15
 * you may not use this file except in compliance with the License.
16
 * You may obtain a copy of the License at
17
 *
18
 * http://www.apache.org/licenses/LICENSE-2.0
19
 *
20
 * Unless required by applicable law or agreed to in writing, software
21
 * distributed under the License is distributed on an "AS IS" BASIS,
22
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
 * See the License for the specific language governing permissions and
24
 * limitations under the License.
25
 */
26

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

    
34
require_once("guiconfig.inc");
35
require_once("filter.inc");
36

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

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

    
103
$if = $_REQUEST['if'];
104

    
105
/* if OLSRD is enabled, allow WAN to house DHCP. */
106
if ($config['installedpackages']['olsrd']) {
107
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
108
		if ($olsrd['enable']) {
109
			$is_olsr_enabled = true;
110
			break;
111
		}
112
	}
113
}
114

    
115
$iflist = get_configured_interface_with_descr();
116
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
117

    
118
/* set the starting interface */
119
if (!$if || !isset($iflist[$if])) {
120
	foreach ($iflist as $ifent => $ifname) {
121
		$oc = $config['interfaces'][$ifent];
122
		$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
123
		    (is_ipaddrv6($oc['ipaddrv6']) &&
124
		    !is_linklocal($oc['ipaddrv6'])));
125

    
126
		if ((!is_array($config['dhcpdv6'][$ifent]) ||
127
		    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
128
		    !$valid_if_ipaddrv6) {
129
			continue;
130
		}
131
		$if = $ifent;
132
		break;
133
	}
134
}
135

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

    
177
if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
178
	$trackifname = $config['interfaces'][$if]['track6-interface'];
179
	$trackcfg = $config['interfaces'][$trackifname];
180
	$ifcfgsn = "64";
181
	$ifcfgip = '::';
182

    
183
	$str_help_mask = dhcpv6_pd_str_help($ifcfgsn);
184
} else {
185
	$ifcfgip = get_interface_ipv6($if);
186
	$ifcfgsn = get_interface_subnetv6($if);
187
}
188

    
189
/*	 set the enabled flag which will tell us if DHCP relay is enabled
190
 *	 on any interface. We will use this to disable DHCP server since
191
 *	 the two are not compatible with each other.
192
 */
193

    
194
$dhcrelay_enabled = false;
195
$dhcrelaycfg = $config['dhcrelay6'];
196

    
197
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
198
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
199

    
200
	foreach ($dhcrelayifs as $dhcrelayif) {
201

    
202
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
203
			$dhcrelay_enabled = true;
204
			break;
205
		}
206
	}
207
}
208

    
209
if (isset($_POST['apply'])) {
210
	$changes_applied = true;
211
	$retval = dhcpv6_apply_changes(false);
212
} elseif (isset($_POST['save'])) {
213
	unset($input_errors);
214

    
215
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
216
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
217
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
218

    
219
	$pconfig = $_POST;
220

    
221
	$numberoptions = array();
222
	for ($x = 0; $x < 99; $x++) {
223
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
224
			$numbervalue = array();
225
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
226
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
227
			$numberoptions['item'][] = $numbervalue;
228
		}
229
	}
230
	// Reload the new pconfig variable that the form uses.
231
	$pconfig['numberoptions'] = $numberoptions;
232

    
233
	/* input validation */
234

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

    
240
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
241
	}
242

    
243
	if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
244
		$input_errors[] = gettext("A valid prefix range must be specified.");
245
	}
246
	if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
247
		$input_errors[] = gettext("A valid prefix range must be specified.");
248
	}
249

    
250
	if ($_POST['prefixrange_from'] && $_POST['prefixrange_to'] &&
251
		$_POST['prefixrange_length']) {
252
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_from'],
253
			$_POST['prefixrange_length']);
254
		$netmask = text_to_compressed_ip6($netmask);
255

    
256
		if ($netmask != text_to_compressed_ip6(strtolower(
257
			$_POST['prefixrange_from']))) {
258
			$input_errors[] = sprintf(gettext(
259
				"Prefix Delegation From address is not a valid IPv6 Netmask for %s"),
260
				$netmask . '/' . $_POST['prefixrange_length']);
261
		}
262

    
263
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
264
			$_POST['prefixrange_length']);
265
		$netmask = text_to_compressed_ip6($netmask);
266

    
267
		if ($netmask != text_to_compressed_ip6(strtolower(
268
			$_POST['prefixrange_to']))) {
269
			$input_errors[] = sprintf(gettext(
270
				"Prefix Delegation To address is not a valid IPv6 Netmask for %s"),
271
				$netmask . '/' . $_POST['prefixrange_length']);
272
		}
273
	}
274

    
275
	$range_from_to_ok = true;
276

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

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

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

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

    
363
	$noip = false;
364
	if (is_array($a_maps)) {
365
		foreach ($a_maps as $map) {
366
			if (empty($map['ipaddrv6'])) {
367
				$noip = true;
368
			}
369
		}
370
	}
371

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

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

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

    
394
		/* Verify static mappings do not overlap:
395
		   - available DHCP range
396
		   - prefix delegation range (FIXME: still need to be completed) */
397
		$dynsubnet_start = inet_pton($_POST['range_from']);
398
		$dynsubnet_end = inet_pton($_POST['range_to']);
399

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

    
414
	if (!$input_errors) {
415
		if (!is_array($config['dhcpdv6'])) {
416
			$config['dhcpdv6'] = array();
417
		}
418
		if (!is_array($config['dhcpdv6'][$if])) {
419
			$config['dhcpdv6'][$if] = array();
420
		}
421
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
422
			$config['dhcpdv6'][$if]['range'] = array();
423
		}
424
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
425
			$config['dhcpdv6'][$if]['prefixrange'] = array();
426
		}
427

    
428
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
429
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
430
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
431
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
432
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
433
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
434
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
435
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
436

    
437
		unset($config['dhcpdv6'][$if]['winsserver']);
438

    
439
		unset($config['dhcpdv6'][$if]['dnsserver']);
440
		if ($_POST['dns1']) {
441
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
442
		}
443
		if ($_POST['dns2']) {
444
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
445
		}
446
		if ($_POST['dns3']) {
447
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
448
		}
449
		if ($_POST['dns4']) {
450
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
451
		}
452

    
453
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
454
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
455
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
456
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
457
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
458
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
459
		$config['dhcpdv6'][$if]['ddnsdomainkeyalgorithm'] = $_POST['ddnsdomainkeyalgorithm'];
460
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
461
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
462
		$config['dhcpdv6'][$if]['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
463
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
464
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
465

    
466
		unset($config['dhcpdv6'][$if]['ntpserver']);
467
		if ($_POST['ntp1']) {
468
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
469
		}
470
		if ($_POST['ntp2']) {
471
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
472
		}
473

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

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

    
485
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
486

    
487
		write_config();
488

    
489
		$changes_applied = true;
490
		$retval = dhcpv6_apply_changes($dhcpdv6_enable_changed);
491
	}
492
}
493

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

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

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

    
520
include("head.inc");
521

    
522
if ($input_errors) {
523
	print_input_errors($input_errors);
524
}
525

    
526
if ($changes_applied) {
527
	print_apply_result_box($retval);
528
}
529

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

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

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

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

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

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

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

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

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

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

    
587
display_top_tabs($tab_array);
588

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

    
594
$form = new Form();
595

    
596
$section = new Form_Section('DHCPv6 Options');
597

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

    
614
if (is_ipaddrv6($ifcfgip)) {
615

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

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

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

    
637
if ($is_olsr_enabled) {
638
	$section->addInput(new Form_Select(
639
	'netmask',
640
	'Subnet Mask',
641
	$pconfig['netmask'],
642
	array_combine(range(128, 1, -1), range(128, 1, -1))
643
	));
644
}
645

    
646
$f1 = new Form_Input(
647
	'range_from',
648
	null,
649
	'text',
650
	$pconfig['range_from']
651
);
652

    
653
$f1->setHelp('From');
654

    
655
$f2 = new Form_Input(
656
	'range_to',
657
	null,
658
	'text',
659
	$pconfig['range_to']
660
);
661

    
662
$f2->setHelp('To');
663

    
664
$group = new Form_Group('*Range');
665

    
666
$group->add($f1);
667
$group->add($f2);
668

    
669
$section->add($group);
670

    
671
$f1 = new Form_Input(
672
	'prefixrange_from',
673
	null,
674
	'text',
675
	$pconfig['prefixrange_from']
676
);
677

    
678
$f1->setHelp('From');
679

    
680
$f2 = new Form_Input(
681
	'prefixrange_to',
682
	null,
683
	'text',
684
	$pconfig['prefixrange_to']
685
);
686

    
687
$f2->setHelp('To');
688

    
689
$group = new Form_Group('Prefix Delegation Range');
690

    
691
$group->add($f1);
692
$group->add($f2);
693

    
694
$section->add($group);
695

    
696
$section->addInput(new Form_Select(
697
	'prefixrange_length',
698
	'Prefix Delegation Size',
699
	$pconfig['prefixrange_length'],
700
	array(
701
		'48' => '48',
702
		'52' => '52',
703
		'56' => '56',
704
		'59' => '59',
705
		'60' => '60',
706
		'61' => '61',
707
		'62' => '62',
708
		'63' => '63',
709
		'64' => '64'
710
		)
711
))->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.');
712

    
713
$group = new Form_Group('DNS Servers');
714

    
715
for ($i=1;$i<=4; $i++) {
716
	$group->add(new Form_input(
717
		'dns' . $i,
718
		null,
719
		'text',
720
		$pconfig['dns' . $i],
721
		['placeholder' => 'DNS ' . $i]
722
	));
723
}
724

    
725
$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.');
726
$section->add($group);
727

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

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

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

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

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

    
767
$btnadv = new Form_Button(
768
	'btnadvdns',
769
	'Display Advanced',
770
	null,
771
	'fa-cog'
772
);
773

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

    
776
$section->addInput(new Form_StaticText(
777
	'Dynamic DNS',
778
	$btnadv
779
));
780

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

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

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

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

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

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

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

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

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

    
857
$btnadv = new Form_Button(
858
	'btnadvntp',
859
	'Display Advanced',
860
	null,
861
	'fa-cog'
862
);
863

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

    
866
$section->addInput(new Form_StaticText(
867
	'NTP servers',
868
	$btnadv
869
));
870

    
871
$group = new Form_Group('NTP Servers');
872

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

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

    
889
$group->addClass('ntpclass');
890

    
891
$section->add($group);
892

    
893
$btnadv = new Form_Button(
894
	'btnadvldap',
895
	'Display Advanced',
896
	null,
897
	'fa-cog'
898
);
899

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

    
902
$section->addInput(new Form_StaticText(
903
	'LDAP',
904
	$btnadv
905
));
906

    
907
$section->addInput(new Form_Input(
908
	'ldap',
909
	'LDAP URI',
910
	'text',
911
	$pconfig['ldap']
912
));
913

    
914
$btnadv = new Form_Button(
915
	'btnadvnetboot',
916
	'Display Advanced',
917
	null,
918
	'fa-cog'
919
);
920

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

    
923
$section->addInput(new Form_StaticText(
924
	'Network booting',
925
	$btnadv
926
));
927

    
928
$section->addInput(new Form_Checkbox(
929
	'shownetboot',
930
	'Network booting',
931
	'Enable Network Booting',
932
	$pconfig['shownetboot']
933
));
934

    
935
$section->addInput(new Form_Input(
936
	'bootfile_url',
937
	'Bootfile URL',
938
	'text',
939
	$pconfig['bootfile_url']
940
));
941

    
942
$btnadv = new Form_Button(
943
	'btnadvopts',
944
	'Display Advanced',
945
	null,
946
	'fa-cog'
947
);
948

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

    
951
$section->addInput(new Form_StaticText(
952
	'Additional BOOTP/DHCP Options',
953
	$btnadv
954
));
955

    
956
$form->add($section);
957

    
958
$title = 'Show Additional BOOTP/DHCP Options';
959

    
960
if (!$pconfig['numberoptions']) {
961
	$noopts = true;
962
	$pconfig['numberoptions'] = array();
963
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
964
} else {
965
	$noopts = false;
966
}
967

    
968
$counter = 0;
969
if (!is_array($pconfig['numberoptions'])) {
970
	$pconfig['numberoptions'] = array();
971
}
972
if (!is_array($pconfig['numberoptions']['item'])) {
973
	$pconfig['numberoptions']['item'] = array();
974
}
975
$last = count($pconfig['numberoptions']['item']) - 1;
976

    
977
foreach ($pconfig['numberoptions']['item'] as $item) {
978
	$group = new Form_Group(null);
979
	$group->addClass('repeatable');
980
	$group->addClass('adnloptions');
981

    
982
	$group->add(new Form_Input(
983
		'number' . $counter,
984
		null,
985
		'text',
986
		$item['number']
987
	))->setHelp($counter == $last ? 'Number':null);
988

    
989
	$group->add(new Form_Input(
990
		'value' . $counter,
991
		null,
992
		'text',
993
		base64_decode($item['value'])
994
	))->setHelp($counter == $last ? 'Value':null);
995

    
996
	$btn = new Form_Button(
997
		'deleterow' . $counter,
998
		'Delete',
999
		null,
1000
		'fa-trash'
1001
	);
1002

    
1003
	$btn->addClass('btn-warning');
1004
	$group->add($btn);
1005
	$section->add($group);
1006
	$counter++;
1007
}
1008

    
1009

    
1010
$btnaddopt = new Form_Button(
1011
	'addrow',
1012
	'Add Option',
1013
	null,
1014
	'fa-plus'
1015
);
1016

    
1017
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
1018

    
1019
$section->addInput($btnaddopt);
1020

    
1021
$section->addInput(new Form_Input(
1022
	'if',
1023
	null,
1024
	'hidden',
1025
	$if
1026
));
1027

    
1028
print($form);
1029

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

    
1097
<nav class="action-buttons">
1098
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1099
		<i class="fa fa-plus icon-embed-btn"></i>
1100
		<?=gettext("Add")?>
1101
	</a>
1102
</nav>
1103

    
1104
<script type="text/javascript">
1105
//<![CDATA[
1106
events.push(function() {
1107

    
1108
	// Show advanced DNS options ======================================================================================
1109
	var showadvdns = false;
1110

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

    
1136
		hideCheckbox('ddnsupdate', !showadvdns);
1137
		hideInput('ddnsdomain', !showadvdns);
1138
		hideCheckbox('ddnsforcehostname', !showadvdns);
1139
		hideInput('ddnsdomainprimary', !showadvdns);
1140
		hideInput('ddnsdomainkeyname', !showadvdns);
1141
		hideInput('ddnsdomainkeyalgorithm', !showadvdns);
1142
		hideInput('ddnsdomainkey', !showadvdns);
1143
		hideInput('ddnsclientupdates', !showadvdns);
1144
		hideCheckbox('ddnsreverse', !showadvdns);
1145

    
1146
		if (showadvdns) {
1147
			text = "<?=gettext('Hide Advanced');?>";
1148
		} else {
1149
			text = "<?=gettext('Display Advanced');?>";
1150
		}
1151
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1152
	}
1153

    
1154
	$('#btnadvdns').click(function(event) {
1155
		show_advdns();
1156
	});
1157

    
1158
	// Show advanced NTP options ======================================================================================
1159
	var showadvntp = false;
1160

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

    
1178
		hideInput('ntp1', !showadvntp);
1179
		hideInput('ntp2', !showadvntp);
1180

    
1181
		if (showadvntp) {
1182
			text = "<?=gettext('Hide Advanced');?>";
1183
		} else {
1184
			text = "<?=gettext('Display Advanced');?>";
1185
		}
1186
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1187
	}
1188

    
1189
	$('#btnadvntp').click(function(event) {
1190
		show_advntp();
1191
	});
1192

    
1193
	// Show advanced LDAP options ======================================================================================
1194
	var showadvldap = false;
1195

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

    
1213
		hideInput('ldap', !showadvldap);
1214

    
1215
		if (showadvldap) {
1216
			text = "<?=gettext('Hide Advanced');?>";
1217
		} else {
1218
			text = "<?=gettext('Display Advanced');?>";
1219
		}
1220
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1221
	}
1222

    
1223
	$('#btnadvldap').click(function(event) {
1224
		show_advldap();
1225
	});
1226

    
1227
	// Show advanced Netboot options ======================================================================================
1228
	var showadvnetboot = false;
1229

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

    
1247
		hideCheckbox('shownetboot', !showadvnetboot);
1248
		hideInput('bootfile_url', !showadvnetboot);
1249

    
1250
		if (showadvnetboot) {
1251
			text = "<?=gettext('Hide Advanced');?>";
1252
		} else {
1253
			text = "<?=gettext('Display Advanced');?>";
1254
		}
1255
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1256
	}
1257

    
1258
	$('#btnadvnetboot').click(function(event) {
1259
		show_advnetboot();
1260
	});
1261

    
1262
	// Show advanced additional opts options ===========================================================================
1263
	var showadvopts = false;
1264

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

    
1283
		hideClass('adnloptions', !showadvopts);
1284
		hideInput('addrow', !showadvopts);
1285

    
1286
		if (showadvopts) {
1287
			text = "<?=gettext('Hide Advanced');?>";
1288
		} else {
1289
			text = "<?=gettext('Display Advanced');?>";
1290
		}
1291
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1292
	}
1293

    
1294
	$('#btnadvopts').click(function(event) {
1295
		show_advopts();
1296
		checkLastRow();
1297
	});
1298

    
1299
	// On initial load
1300
	show_advdns(true);
1301
	show_advntp(true);
1302
	show_advldap(true);
1303
	show_advnetboot(true);
1304
	show_advopts(true);
1305
	if ($('#enable').prop('checked')) {
1306
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1307
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1308
	} else {
1309
		hideClass('adnloptions', true);
1310
		hideInput('addrow', true);
1311
	}
1312

    
1313
});
1314
//]]>
1315
</script>
1316

    
1317
<?php include('foot.inc');
(128-128/235)