Project

General

Profile

Download (38.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * services_dhcpv6.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-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'][$if])) {
416
			$config['dhcpdv6'][$if] = array();
417
		}
418
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
419
			$config['dhcpdv6'][$if]['range'] = array();
420
		}
421
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
422
			$config['dhcpdv6'][$if]['prefixrange'] = array();
423
		}
424

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

    
434
		unset($config['dhcpdv6'][$if]['winsserver']);
435

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

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

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

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

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

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

    
484
		write_config();
485

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

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

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

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

    
517
include("head.inc");
518

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

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

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

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

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

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

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

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

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

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

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

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

    
584
display_top_tabs($tab_array);
585

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

    
591
$form = new Form();
592

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

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

    
611
if (is_ipaddrv6($ifcfgip)) {
612

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

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

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

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

    
643
$f1 = new Form_Input(
644
	'range_from',
645
	null,
646
	'text',
647
	$pconfig['range_from']
648
);
649

    
650
$f1->setHelp('From');
651

    
652
$f2 = new Form_Input(
653
	'range_to',
654
	null,
655
	'text',
656
	$pconfig['range_to']
657
);
658

    
659
$f2->setHelp('To');
660

    
661
$group = new Form_Group('*Range');
662

    
663
$group->add($f1);
664
$group->add($f2);
665

    
666
$section->add($group);
667

    
668
$f1 = new Form_Input(
669
	'prefixrange_from',
670
	null,
671
	'text',
672
	$pconfig['prefixrange_from']
673
);
674

    
675
$f1->setHelp('From');
676

    
677
$f2 = new Form_Input(
678
	'prefixrange_to',
679
	null,
680
	'text',
681
	$pconfig['prefixrange_to']
682
);
683

    
684
$f2->setHelp('To');
685

    
686
$group = new Form_Group('Prefix Delegation Range');
687

    
688
$group->add($f1);
689
$group->add($f2);
690

    
691
$section->add($group);
692

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

    
710
$group = new Form_Group('DNS Servers');
711

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

    
722
$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.');
723
$section->add($group);
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->addClass('ntpclass');
887

    
888
$section->add($group);
889

    
890
$btnadv = new Form_Button(
891
	'btnadvldap',
892
	'Display Advanced',
893
	null,
894
	'fa-cog'
895
);
896

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

    
899
$section->addInput(new Form_StaticText(
900
	'LDAP',
901
	$btnadv
902
));
903

    
904
$section->addInput(new Form_Input(
905
	'ldap',
906
	'LDAP URI',
907
	'text',
908
	$pconfig['ldap']
909
));
910

    
911
$btnadv = new Form_Button(
912
	'btnadvnetboot',
913
	'Display Advanced',
914
	null,
915
	'fa-cog'
916
);
917

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

    
920
$section->addInput(new Form_StaticText(
921
	'Network booting',
922
	$btnadv
923
));
924

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

    
932
$section->addInput(new Form_Input(
933
	'bootfile_url',
934
	'Bootfile URL',
935
	'text',
936
	$pconfig['bootfile_url']
937
));
938

    
939
$btnadv = new Form_Button(
940
	'btnadvopts',
941
	'Display Advanced',
942
	null,
943
	'fa-cog'
944
);
945

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

    
948
$section->addInput(new Form_StaticText(
949
	'Additional BOOTP/DHCP Options',
950
	$btnadv
951
));
952

    
953
$form->add($section);
954

    
955
$title = 'Show Additional BOOTP/DHCP Options';
956

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

    
964
$counter = 0;
965
$last = count($pconfig['numberoptions']['item']) - 1;
966

    
967
foreach ($pconfig['numberoptions']['item'] as $item) {
968
	$group = new Form_Group(null);
969
	$group->addClass('repeatable');
970
	$group->addClass('adnloptions');
971

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

    
979
	$group->add(new Form_Input(
980
		'value' . $counter,
981
		null,
982
		'text',
983
		base64_decode($item['value'])
984
	))->setHelp($counter == $last ? 'Value':null);
985

    
986
	$btn = new Form_Button(
987
		'deleterow' . $counter,
988
		'Delete',
989
		null,
990
		'fa-trash'
991
	);
992

    
993
	$btn->addClass('btn-warning');
994
	$group->add($btn);
995
	$section->add($group);
996
	$counter++;
997
}
998

    
999

    
1000
$btnaddopt = new Form_Button(
1001
	'addrow',
1002
	'Add Option',
1003
	null,
1004
	'fa-plus'
1005
);
1006

    
1007
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
1008

    
1009
$section->addInput($btnaddopt);
1010

    
1011
$section->addInput(new Form_Input(
1012
	'if',
1013
	null,
1014
	'hidden',
1015
	$if
1016
));
1017

    
1018
print($form);
1019

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

    
1087
<nav class="action-buttons">
1088
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1089
		<i class="fa fa-plus icon-embed-btn"></i>
1090
		<?=gettext("Add")?>
1091
	</a>
1092
</nav>
1093

    
1094
<script type="text/javascript">
1095
//<![CDATA[
1096
events.push(function() {
1097

    
1098
	// Show advanced DNS options ======================================================================================
1099
	var showadvdns = false;
1100

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

    
1126
		hideCheckbox('ddnsupdate', !showadvdns);
1127
		hideInput('ddnsdomain', !showadvdns);
1128
		hideCheckbox('ddnsforcehostname', !showadvdns);
1129
		hideInput('ddnsdomainprimary', !showadvdns);
1130
		hideInput('ddnsdomainkeyname', !showadvdns);
1131
		hideInput('ddnsdomainkeyalgorithm', !showadvdns);
1132
		hideInput('ddnsdomainkey', !showadvdns);
1133
		hideInput('ddnsclientupdates', !showadvdns);
1134
		hideCheckbox('ddnsreverse', !showadvdns);
1135

    
1136
		if (showadvdns) {
1137
			text = "<?=gettext('Hide Advanced');?>";
1138
		} else {
1139
			text = "<?=gettext('Display Advanced');?>";
1140
		}
1141
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1142
	}
1143

    
1144
	$('#btnadvdns').click(function(event) {
1145
		show_advdns();
1146
	});
1147

    
1148
	// Show advanced NTP options ======================================================================================
1149
	var showadvntp = false;
1150

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

    
1168
		hideInput('ntp1', !showadvntp);
1169
		hideInput('ntp2', !showadvntp);
1170

    
1171
		if (showadvntp) {
1172
			text = "<?=gettext('Hide Advanced');?>";
1173
		} else {
1174
			text = "<?=gettext('Display Advanced');?>";
1175
		}
1176
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1177
	}
1178

    
1179
	$('#btnadvntp').click(function(event) {
1180
		show_advntp();
1181
	});
1182

    
1183
	// Show advanced LDAP options ======================================================================================
1184
	var showadvldap = false;
1185

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

    
1203
		hideInput('ldap', !showadvldap);
1204

    
1205
		if (showadvldap) {
1206
			text = "<?=gettext('Hide Advanced');?>";
1207
		} else {
1208
			text = "<?=gettext('Display Advanced');?>";
1209
		}
1210
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1211
	}
1212

    
1213
	$('#btnadvldap').click(function(event) {
1214
		show_advldap();
1215
	});
1216

    
1217
	// Show advanced Netboot options ======================================================================================
1218
	var showadvnetboot = false;
1219

    
1220
	function show_advnetboot(ispageload) {
1221
		var text;
1222
		// On page load decide the initial state based on the data.
1223
		if (ispageload) {
1224
<?php
1225
			if (!$pconfig['shownetboot'] && empty($pconfig['bootfile_url'])) {
1226
				$showadv = false;
1227
			} else {
1228
				$showadv = true;
1229
			}
1230
?>
1231
			showadvnetboot = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1232
		} else {
1233
			// It was a click, swap the state.
1234
			showadvnetboot = !showadvnetboot;
1235
		}
1236

    
1237
		hideCheckbox('shownetboot', !showadvnetboot);
1238
		hideInput('bootfile_url', !showadvnetboot);
1239

    
1240
		if (showadvnetboot) {
1241
			text = "<?=gettext('Hide Advanced');?>";
1242
		} else {
1243
			text = "<?=gettext('Display Advanced');?>";
1244
		}
1245
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1246
	}
1247

    
1248
	$('#btnadvnetboot').click(function(event) {
1249
		show_advnetboot();
1250
	});
1251

    
1252
	// Show advanced additional opts options ===========================================================================
1253
	var showadvopts = false;
1254

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

    
1273
		hideClass('adnloptions', !showadvopts);
1274
		hideInput('addrow', !showadvopts);
1275

    
1276
		if (showadvopts) {
1277
			text = "<?=gettext('Hide Advanced');?>";
1278
		} else {
1279
			text = "<?=gettext('Display Advanced');?>";
1280
		}
1281
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1282
	}
1283

    
1284
	$('#btnadvopts').click(function(event) {
1285
		show_advopts();
1286
		checkLastRow();
1287
	});
1288

    
1289
	// On initial load
1290
	show_advdns(true);
1291
	show_advntp(true);
1292
	show_advldap(true);
1293
	show_advnetboot(true);
1294
	show_advopts(true);
1295
	if ($('#enable').prop('checked')) {
1296
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1297
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1298
	} else {
1299
		hideClass('adnloptions', true);
1300
		hideInput('addrow', true);
1301
	}
1302

    
1303
});
1304
//]]>
1305
</script>
1306

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