Project

General

Profile

Download (37.6 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-2016 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['ddnsdomainkey'] = $config['dhcpdv6'][$if]['ddnsdomainkey'];
158
	$pconfig['ddnsupdate'] = isset($config['dhcpdv6'][$if]['ddnsupdate']);
159
	$pconfig['ddnsforcehostname'] = isset($config['dhcpdv6'][$if]['ddnsforcehostname']);
160
	$pconfig['ddnsreverse'] = isset($config['dhcpdv6'][$if]['ddnsreverse']);
161
	$pconfig['ddnsclientupdates'] = $config['dhcpdv6'][$if]['ddnsclientupdates'];
162
	list($pconfig['ntp1'], $pconfig['ntp2']) = $config['dhcpdv6'][$if]['ntpserver'];
163
	$pconfig['tftp'] = $config['dhcpdv6'][$if]['tftp'];
164
	$pconfig['ldap'] = $config['dhcpdv6'][$if]['ldap'];
165
	$pconfig['netboot'] = isset($config['dhcpdv6'][$if]['netboot']);
166
	$pconfig['bootfile_url'] = $config['dhcpdv6'][$if]['bootfile_url'];
167
	$pconfig['netmask'] = $config['dhcpdv6'][$if]['netmask'];
168
	$pconfig['numberoptions'] = $config['dhcpdv6'][$if]['numberoptions'];
169
	$pconfig['dhcpv6leaseinlocaltime'] = $config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'];
170
	if (!is_array($config['dhcpdv6'][$if]['staticmap'])) {
171
		$config['dhcpdv6'][$if]['staticmap'] = array();
172
	}
173
	$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
174
}
175

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

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

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

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

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

    
199
	foreach ($dhcrelayifs as $dhcrelayif) {
200

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

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

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

    
218
	$pconfig = $_POST;
219

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

    
232
	/* input validation */
233

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

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

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

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

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

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

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

    
274
	$range_from_to_ok = true;
275

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

    
313
	if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
314
		$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
315
	}
316
	if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
317
		$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
318
	}
319
	if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain']))) {
320
		$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
321
	}
322
	if (($_POST['ddnsdomain'] && !is_ipaddrv4($_POST['ddnsdomainprimary']))) {
323
		$input_errors[] = gettext("A valid primary domain name server IPv4 address must be specified for the dynamic domain name.");
324
	}
325
	if (($_POST['ddnsdomainkey'] && !$_POST['ddnsdomainkeyname']) ||
326
		($_POST['ddnsdomainkeyname'] && !$_POST['ddnsdomainkey'])) {
327
		$input_errors[] = gettext("Both a valid domain key and key name 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]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
457
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
458
		$config['dhcpdv6'][$if]['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
459
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
460
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
461

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

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

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

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

    
483
		write_config();
484

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

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

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

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

    
516
include("head.inc");
517

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

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

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

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

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

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

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

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

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

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

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

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

    
583
display_top_tabs($tab_array);
584

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

    
590
$form = new Form();
591

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

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

    
610
if (is_ipaddrv6($ifcfgip)) {
611

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
949
$counter = 0;
950
$last = count($pconfig['numberoptions']['item']) - 1;
951

    
952
foreach ($pconfig['numberoptions']['item'] as $item) {
953
	$group = new Form_Group(null);
954
	$group->addClass('repeatable');
955
	$group->addClass('adnloptions');
956

    
957
	$group->add(new Form_Input(
958
		'number' . $counter,
959
		null,
960
		'text',
961
		$item['number']
962
	))->setHelp($counter == $last ? 'Number':null);
963

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

    
971
	$btn = new Form_Button(
972
		'deleterow' . $counter,
973
		'Delete',
974
		null,
975
		'fa-trash'
976
	);
977

    
978
	$btn->addClass('btn-warning');
979
	$group->add($btn);
980
	$section->add($group);
981
	$counter++;
982
}
983

    
984

    
985
$btnaddopt = new Form_Button(
986
	'addrow',
987
	'Add Option',
988
	null,
989
	'fa-plus'
990
);
991

    
992
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
993

    
994
$section->addInput($btnaddopt);
995

    
996
$section->addInput(new Form_Input(
997
	'if',
998
	null,
999
	'hidden',
1000
	$if
1001
));
1002

    
1003
print($form);
1004

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

    
1072
<nav class="action-buttons">
1073
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1074
		<i class="fa fa-plus icon-embed-btn"></i>
1075
		<?=gettext("Add")?>
1076
	</a>
1077
</nav>
1078

    
1079
<script type="text/javascript">
1080
//<![CDATA[
1081
events.push(function() {
1082

    
1083
	// Show advanced DNS options ======================================================================================
1084
	var showadvdns = false;
1085

    
1086
	function show_advdns(ispageload) {
1087
		var text;
1088
		// On page load decide the initial state based on the data.
1089
		if (ispageload) {
1090
<?php
1091
			if (!$pconfig['ddnsupdate'] &&
1092
			    !$pconfig['ddnsforcehostname'] &&
1093
			    empty($pconfig['ddnsdomain']) &&
1094
			    empty($pconfig['ddnsdomainprimary']) &&
1095
			    empty($pconfig['ddnsdomainkeyname']) &&
1096
			    empty($pconfig['ddnsdomainkey']) &&
1097
			    (empty($pconfig['ddnsclientupdates']) || ($pconfig['ddnsclientupdates'] == "allow")) &&
1098
			    !$pconfig['ddnsreverse']) {
1099
				$showadv = false;
1100
			} else {
1101
				$showadv = true;
1102
			}
1103
?>
1104
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1105
		} else {
1106
			// It was a click, swap the state.
1107
			showadvdns = !showadvdns;
1108
		}
1109

    
1110
		hideCheckbox('ddnsupdate', !showadvdns);
1111
		hideInput('ddnsdomain', !showadvdns);
1112
		hideCheckbox('ddnsforcehostname', !showadvdns);
1113
		hideInput('ddnsdomainprimary', !showadvdns);
1114
		hideInput('ddnsdomainkeyname', !showadvdns);
1115
		hideInput('ddnsdomainkey', !showadvdns);
1116
		hideInput('ddnsclientupdates', !showadvdns);
1117
		hideCheckbox('ddnsreverse', !showadvdns);
1118

    
1119
		if (showadvdns) {
1120
			text = "<?=gettext('Hide Advanced');?>";
1121
		} else {
1122
			text = "<?=gettext('Display Advanced');?>";
1123
		}
1124
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1125
	}
1126

    
1127
	$('#btnadvdns').click(function(event) {
1128
		show_advdns();
1129
	});
1130

    
1131
	// Show advanced NTP options ======================================================================================
1132
	var showadvntp = false;
1133

    
1134
	function show_advntp(ispageload) {
1135
		var text;
1136
		// On page load decide the initial state based on the data.
1137
		if (ispageload) {
1138
<?php
1139
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1140
				$showadv = false;
1141
			} else {
1142
				$showadv = true;
1143
			}
1144
?>
1145
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1146
		} else {
1147
			// It was a click, swap the state.
1148
			showadvntp = !showadvntp;
1149
		}
1150

    
1151
		hideInput('ntp1', !showadvntp);
1152
		hideInput('ntp2', !showadvntp);
1153

    
1154
		if (showadvntp) {
1155
			text = "<?=gettext('Hide Advanced');?>";
1156
		} else {
1157
			text = "<?=gettext('Display Advanced');?>";
1158
		}
1159
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1160
	}
1161

    
1162
	$('#btnadvntp').click(function(event) {
1163
		show_advntp();
1164
	});
1165

    
1166
	// Show advanced LDAP options ======================================================================================
1167
	var showadvldap = false;
1168

    
1169
	function show_advldap(ispageload) {
1170
		var text;
1171
		// On page load decide the initial state based on the data.
1172
		if (ispageload) {
1173
<?php
1174
			if (empty($pconfig['ldap'])) {
1175
				$showadv = false;
1176
			} else {
1177
				$showadv = true;
1178
			}
1179
?>
1180
			showadvldap = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1181
		} else {
1182
			// It was a click, swap the state.
1183
			showadvldap = !showadvldap;
1184
		}
1185

    
1186
		hideInput('ldap', !showadvldap);
1187

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

    
1196
	$('#btnadvldap').click(function(event) {
1197
		show_advldap();
1198
	});
1199

    
1200
	// Show advanced Netboot options ======================================================================================
1201
	var showadvnetboot = false;
1202

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

    
1220
		hideCheckbox('shownetboot', !showadvnetboot);
1221
		hideInput('bootfile_url', !showadvnetboot);
1222

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

    
1231
	$('#btnadvnetboot').click(function(event) {
1232
		show_advnetboot();
1233
	});
1234

    
1235
	// Show advanced additional opts options ===========================================================================
1236
	var showadvopts = false;
1237

    
1238
	function show_advopts(ispageload) {
1239
		var text;
1240
		// On page load decide the initial state based on the data.
1241
		if (ispageload) {
1242
<?php
1243
			if (empty($pconfig['numberoptions']) ||
1244
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1245
				$showadv = false;
1246
			} else {
1247
				$showadv = true;
1248
			}
1249
?>
1250
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1251
		} else {
1252
			// It was a click, swap the state.
1253
			showadvopts = !showadvopts;
1254
		}
1255

    
1256
		hideClass('adnloptions', !showadvopts);
1257
		hideInput('addrow', !showadvopts);
1258

    
1259
		if (showadvopts) {
1260
			text = "<?=gettext('Hide Advanced');?>";
1261
		} else {
1262
			text = "<?=gettext('Display Advanced');?>";
1263
		}
1264
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1265
	}
1266

    
1267
	$('#btnadvopts').click(function(event) {
1268
		show_advopts();
1269
		checkLastRow();
1270
	});
1271

    
1272
	// On initial load
1273
	show_advdns(true);
1274
	show_advntp(true);
1275
	show_advldap(true);
1276
	show_advnetboot(true);
1277
	show_advopts(true);
1278
	if ($('#enable').prop('checked')) {
1279
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1280
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1281
	} else {
1282
		hideClass('adnloptions', true);
1283
		hideInput('addrow', true);
1284
	}
1285

    
1286
});
1287
//]]>
1288
</script>
1289

    
1290
<?php include('foot.inc');
(123-123/228)