Project

General

Profile

Download (38.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * services_dhcpv6.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-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
$iflist = get_configured_interface_with_descr();
105
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
106

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

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

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

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

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

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

    
184
$dhcrelay_enabled = false;
185
$dhcrelaycfg = $config['dhcrelay6'];
186

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

    
190
	foreach ($dhcrelayifs as $dhcrelayif) {
191

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

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

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

    
209
	$pconfig = $_POST;
210

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

    
223
	/* input validation */
224

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

    
230
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
231
	}
232

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

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

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

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

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

    
265
	$range_from_to_ok = true;
266

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

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

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

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

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

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

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

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

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

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

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

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

    
427
		unset($config['dhcpdv6'][$if]['winsserver']);
428

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

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

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

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

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

    
475
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
476

    
477
		write_config();
478

    
479
		$changes_applied = true;
480
		$retval = dhcpv6_apply_changes($dhcpdv6_enable_changed);
481
	}
482
}
483

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

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

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

    
510
include("head.inc");
511

    
512
if ($input_errors) {
513
	print_input_errors($input_errors);
514
}
515

    
516
if ($changes_applied) {
517
	print_apply_result_box($retval);
518
}
519

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

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

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

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

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

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

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

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

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

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

    
577
display_top_tabs($tab_array);
578

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

    
584
$form = new Form();
585

    
586
$section = new Form_Section('DHCPv6 Options');
587

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

    
604
if (is_ipaddrv6($ifcfgip)) {
605

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

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

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

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

    
634
$f1->setHelp('From');
635

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

    
643
$f2->setHelp('To');
644

    
645
$group = new Form_Group('*Range');
646

    
647
$group->add($f1);
648
$group->add($f2);
649

    
650
$section->add($group);
651

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

    
659
$f1->setHelp('From');
660

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

    
668
$f2->setHelp('To');
669

    
670
$group = new Form_Group('Prefix Delegation Range');
671

    
672
$group->add($f1);
673
$group->add($f2);
674

    
675
$section->add($group);
676

    
677
$section->addInput(new Form_Select(
678
	'prefixrange_length',
679
	'Prefix Delegation Size',
680
	$pconfig['prefixrange_length'],
681
	array(
682
		'48' => '48',
683
		'52' => '52',
684
		'56' => '56',
685
		'59' => '59',
686
		'60' => '60',
687
		'61' => '61',
688
		'62' => '62',
689
		'63' => '63',
690
		'64' => '64'
691
		)
692
))->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.');
693

    
694
$group = new Form_Group('DNS Servers');
695

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

    
706
$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.');
707
$section->add($group);
708

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
990

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

    
998
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
999

    
1000
$section->addInput($btnaddopt);
1001

    
1002
$section->addInput(new Form_Input(
1003
	'if',
1004
	null,
1005
	'hidden',
1006
	$if
1007
));
1008

    
1009
print($form);
1010

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

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

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

    
1089
	// Show advanced DNS options ======================================================================================
1090
	var showadvdns = false;
1091

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

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

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

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

    
1139
	// Show advanced NTP options ======================================================================================
1140
	var showadvntp = false;
1141

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

    
1159
		hideInput('ntp1', !showadvntp);
1160
		hideInput('ntp2', !showadvntp);
1161

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

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

    
1174
	// Show advanced LDAP options ======================================================================================
1175
	var showadvldap = false;
1176

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

    
1194
		hideInput('ldap', !showadvldap);
1195

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

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

    
1208
	// Show advanced Netboot options ======================================================================================
1209
	var showadvnetboot = false;
1210

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

    
1228
		hideCheckbox('netboot', !showadvnetboot);
1229
		hideInput('bootfile_url', !showadvnetboot);
1230

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

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

    
1243
	// Show advanced additional opts options ===========================================================================
1244
	var showadvopts = false;
1245

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

    
1264
		hideClass('adnloptions', !showadvopts);
1265
		hideInput('addrow', !showadvopts);
1266

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

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

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

    
1294
});
1295
//]]>
1296
</script>
1297

    
1298
<?php include('foot.inc');
(127-127/234)