Project

General

Profile

Download (38.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * services_dhcpv6.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-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
 * Redistribution and use in source and binary forms, with or without
15
 * modification, are permitted provided that the following conditions are met:
16
 *
17
 * 1. Redistributions of source code must retain the above copyright notice,
18
 *    this list of conditions and the following disclaimer.
19
 *
20
 * 2. Redistributions in binary form must reproduce the above copyright
21
 *    notice, this list of conditions and the following disclaimer in
22
 *    the documentation and/or other materials provided with the
23
 *    distribution.
24
 *
25
 * 3. All advertising materials mentioning features or use of this software
26
 *    must display the following acknowledgment:
27
 *    "This product includes software developed by the pfSense Project
28
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
29
 *
30
 * 4. The names "pfSense" and "pfSense Project" must not be used to
31
 *    endorse or promote products derived from this software without
32
 *    prior written permission. For written permission, please contact
33
 *    coreteam@pfsense.org.
34
 *
35
 * 5. Products derived from this software may not be called "pfSense"
36
 *    nor may "pfSense" appear in their names without prior written
37
 *    permission of the Electric Sheep Fencing, LLC.
38
 *
39
 * 6. Redistributions of any form whatsoever must retain the following
40
 *    acknowledgment:
41
 *
42
 * "This product includes software developed by the pfSense Project
43
 * for use in the pfSense software distribution (http://www.pfsense.org/).
44
 *
45
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
 * OF THE POSSIBILITY OF SUCH DAMAGE.
57
 */
58

    
59
##|+PRIV
60
##|*IDENT=page-services-dhcpv6server
61
##|*NAME=Services: DHCPv6 Server
62
##|*DESCR=Allow access to the 'Services: DHCPv6 Server' page.
63
##|*MATCH=services_dhcpv6.php*
64
##|-PRIV
65

    
66
require_once("guiconfig.inc");
67
require_once("filter.inc");
68

    
69
function dhcpv6_apply_changes($dhcpdv6_enable_changed) {
70
	$retval = 0;
71
	$retvaldhcp = 0;
72
	$retvaldns = 0;
73
	/* Stop DHCPv6 so we can cleanup leases */
74
	killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
75
	// dhcp_clean_leases();
76
	/* dnsmasq_configure calls dhcpd_configure */
77
	/* no need to restart dhcpd twice */
78
	if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic']))	{
79
		$retvaldns = services_dnsmasq_configure();
80
		if ($retvaldns == 0) {
81
			clear_subsystem_dirty('hosts');
82
			clear_subsystem_dirty('staticmaps');
83
		}
84
	} else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) {
85
		$retvaldns = services_unbound_configure();
86
		if ($retvaldns == 0) {
87
			clear_subsystem_dirty('unbound');
88
			clear_subsystem_dirty('staticmaps');
89
		}
90
	} else {
91
		$retvaldhcp = services_dhcpd_configure();
92
		if ($retvaldhcp == 0) {
93
			clear_subsystem_dirty('staticmaps');
94
		}
95
	}
96
	if ($dhcpdv6_enable_changed) {
97
		$retvalfc = filter_configure();
98
	}
99
	if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) {
100
		$retval = 1;
101
	}
102
	return get_std_save_message($retval);
103
}
104

    
105
if (!$g['services_dhcp_server_enable']) {
106
	header("Location: /");
107
	exit;
108
}
109

    
110
$if = $_GET['if'];
111
if ($_POST['if']) {
112
	$if = $_POST['if'];
113
}
114

    
115
/* if OLSRD is enabled, allow WAN to house DHCP. */
116
if ($config['installedpackages']['olsrd']) {
117
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
118
		if ($olsrd['enable']) {
119
			$is_olsr_enabled = true;
120
			break;
121
		}
122
	}
123
}
124

    
125
$iflist = get_configured_interface_with_descr();
126
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
127

    
128
/* set the starting interface */
129
if (!$if || !isset($iflist[$if])) {
130
	foreach ($iflist as $ifent => $ifname) {
131
		$oc = $config['interfaces'][$ifent];
132
		$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
133
		    (is_ipaddrv6($oc['ipaddrv6']) &&
134
		    !is_linklocal($oc['ipaddrv6'])));
135

    
136
		if ((!is_array($config['dhcpdv6'][$ifent]) ||
137
		    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
138
		    !$valid_if_ipaddrv6) {
139
			continue;
140
		}
141
		$if = $ifent;
142
		break;
143
	}
144
}
145

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

    
186
if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
187
	$trackifname = $config['interfaces'][$if]['track6-interface'];
188
	$trackcfg = $config['interfaces'][$trackifname];
189
	$ifcfgsn = "64";
190
	$ifcfgip = '::';
191

    
192
	$str_help_mask = dhcpv6_pd_str_help($ifcfgsn);
193
} else {
194
	$ifcfgip = get_interface_ipv6($if);
195
	$ifcfgsn = get_interface_subnetv6($if);
196
}
197

    
198
/*	 set the enabled flag which will tell us if DHCP relay is enabled
199
 *	 on any interface. We will use this to disable DHCP server since
200
 *	 the two are not compatible with each other.
201
 */
202

    
203
$dhcrelay_enabled = false;
204
$dhcrelaycfg = $config['dhcrelay6'];
205

    
206
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
207
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
208

    
209
	foreach ($dhcrelayifs as $dhcrelayif) {
210

    
211
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
212
			$dhcrelay_enabled = true;
213
			break;
214
		}
215
	}
216
}
217

    
218
if (isset($_POST['apply'])) {
219
	$savemsg = dhcpv6_apply_changes(false);
220
} elseif (isset($_POST['save'])) {
221
	unset($input_errors);
222

    
223
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
224
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
225
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
226

    
227
	$pconfig = $_POST;
228

    
229
	$numberoptions = array();
230
	for ($x = 0; $x < 99; $x++) {
231
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
232
			$numbervalue = array();
233
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
234
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
235
			$numberoptions['item'][] = $numbervalue;
236
		}
237
	}
238
	// Reload the new pconfig variable that the form uses.
239
	$pconfig['numberoptions'] = $numberoptions;
240

    
241
	/* input validation */
242

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

    
248
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
249
	}
250

    
251
	if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
252
		$input_errors[] = gettext("A valid prefix range must be specified.");
253
	}
254
	if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
255
		$input_errors[] = gettext("A valid prefix range must be specified.");
256
	}
257

    
258
	if ($_POST['prefixrange_from'] && $_POST['prefixrange_to'] &&
259
		$_POST['prefixrange_length']) {
260
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_from'],
261
			$_POST['prefixrange_length']);
262
		$netmask = text_to_compressed_ip6($netmask);
263

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

    
271
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
272
			$_POST['prefixrange_length']);
273
		$netmask = text_to_compressed_ip6($netmask);
274

    
275
		if ($netmask != text_to_compressed_ip6(strtolower(
276
			$_POST['prefixrange_to']))) {
277
			$input_errors[] = sprintf(gettext(
278
				"Prefix Delegation To address is not a valid IPv6 Netmask for %s"),
279
				$netmask . '/' . $_POST['prefixrange_length']);
280
		}
281
	}
282

    
283
	$range_from_to_ok = true;
284

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

    
322
	if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
323
		$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
324
	}
325
	if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
326
		$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
327
	}
328
	if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain']))) {
329
		$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
330
	}
331
	if (($_POST['ddnsdomain'] && !is_ipaddrv4($_POST['ddnsdomainprimary']))) {
332
		$input_errors[] = gettext("A valid primary domain name server IPv4 address must be specified for the dynamic domain name.");
333
	}
334
	if (($_POST['ddnsdomainkey'] && !$_POST['ddnsdomainkeyname']) ||
335
		($_POST['ddnsdomainkeyname'] && !$_POST['ddnsdomainkey'])) {
336
		$input_errors[] = gettext("Both a valid domain key and key name must be specified.");
337
	}
338
	if ($_POST['domainsearchlist']) {
339
		$domain_array=preg_split("/[ ;]+/", $_POST['domainsearchlist']);
340
		foreach ($domain_array as $curdomain) {
341
			if (!is_domain($curdomain)) {
342
				$input_errors[] = gettext("A valid domain search list must be specified.");
343
				break;
344
			}
345
		}
346
	}
347

    
348
	if (($_POST['ntp1'] && !is_ipaddrv6($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv6($_POST['ntp2']))) {
349
		$input_errors[] = gettext("A valid IPv6 address must be specified for the primary/secondary NTP servers.");
350
	}
351
	if (($_POST['domain'] && !is_domain($_POST['domain']))) {
352
		$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
353
	}
354
	if ($_POST['tftp'] && !is_ipaddr($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
355
		$input_errors[] = gettext("A valid IPv6 address or hostname must be specified for the TFTP server.");
356
	}
357
	if (($_POST['bootfile_url'] && !is_URL($_POST['bootfile_url']))) {
358
		$input_errors[] = gettext("A valid URL must be specified for the network bootfile.");
359
	}
360

    
361
	// Disallow a range that includes the virtualip
362
	if ($range_from_to_ok && is_array($config['virtualip']['vip'])) {
363
		foreach ($config['virtualip']['vip'] as $vip) {
364
			if ($vip['interface'] == $if) {
365
				if ($vip['subnetv6'] && is_inrange_v6($vip['subnetv6'], $_POST['range_from'], $_POST['range_to'])) {
366
					$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IPv6 address %s."), $vip['subnetv6']);
367
				}
368
			}
369
		}
370
	}
371

    
372
	$noip = false;
373
	if (is_array($a_maps)) {
374
		foreach ($a_maps as $map) {
375
			if (empty($map['ipaddrv6'])) {
376
				$noip = true;
377
			}
378
		}
379
	}
380

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

    
386
	// 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.
387
	if (!$input_errors && $_POST['range_from'] && $_POST['range_to']) {
388
		/* make sure the range lies within the current subnet */
389
		$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
390
		$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
391

    
392
		if (is_ipaddrv6($ifcfgip)) {
393
			if ((!is_inrange_v6($_POST['range_from'], $subnet_start, $subnet_end)) ||
394
				(!is_inrange_v6($_POST['range_to'], $subnet_start, $subnet_end))) {
395
				$input_errors[] = gettext("The specified range lies outside of the current subnet.");
396
			}
397
		}
398
		/* "from" cannot be higher than "to" */
399
		if (inet_pton($_POST['range_from']) > inet_pton($_POST['range_to'])) {
400
			$input_errors[] = gettext("The range is invalid (first element higher than second element).");
401
		}
402

    
403
		/* Verify static mappings do not overlap:
404
		   - available DHCP range
405
		   - prefix delegation range (FIXME: still need to be completed) */
406
		$dynsubnet_start = inet_pton($_POST['range_from']);
407
		$dynsubnet_end = inet_pton($_POST['range_to']);
408

    
409
		if (is_array($a_maps)) {
410
			foreach ($a_maps as $map) {
411
				if (empty($map['ipaddrv6'])) {
412
					continue;
413
				}
414
				if ((inet_pton($map['ipaddrv6']) > $dynsubnet_start) &&
415
					(inet_pton($map['ipaddrv6']) < $dynsubnet_end)) {
416
					$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
417
					break;
418
				}
419
			}
420
		}
421
	}
422

    
423
	if (!$input_errors) {
424
		if (!is_array($config['dhcpdv6'][$if])) {
425
			$config['dhcpdv6'][$if] = array();
426
		}
427
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
428
			$config['dhcpdv6'][$if]['range'] = array();
429
		}
430
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
431
			$config['dhcpdv6'][$if]['prefixrange'] = array();
432
		}
433

    
434
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
435
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
436
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
437
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
438
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
439
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
440
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
441
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
442

    
443
		unset($config['dhcpdv6'][$if]['winsserver']);
444

    
445
		unset($config['dhcpdv6'][$if]['dnsserver']);
446
		if ($_POST['dns1']) {
447
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
448
		}
449
		if ($_POST['dns2']) {
450
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
451
		}
452
		if ($_POST['dns3']) {
453
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
454
		}
455
		if ($_POST['dns4']) {
456
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
457
		}
458

    
459
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
460
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
461
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
462
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
463
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
464
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
465
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
466
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
467
		$config['dhcpdv6'][$if]['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
468
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
469
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
470

    
471
		unset($config['dhcpdv6'][$if]['ntpserver']);
472
		if ($_POST['ntp1']) {
473
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
474
		}
475
		if ($_POST['ntp2']) {
476
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
477
		}
478

    
479
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
480
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
481
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
482
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
483
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
484

    
485
		// Handle the custom options rowhelper
486
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
487
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
488
		}
489

    
490
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
491

    
492
		write_config();
493

    
494
		$savemsg = dhcpv6_apply_changes($dhcpdv6_enable_changed);
495
	}
496
}
497

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

    
513
$pgtitle = array(gettext("Services"), htmlspecialchars(gettext("DHCPv6 Server & RA")));
514
$pglinks = array("", "services_dhcpv6.php");
515

    
516
if (!empty($if) && isset($iflist[$if])) {
517
	$pgtitle[] = $iflist[$if];
518
	$pglinks[] = "@self";
519
	$pgtitle[] = gettext("DHCPv6 Server");
520
	$pglinks[] = "@self";
521
}
522
$shortcut_section = "dhcp6";
523

    
524
include("head.inc");
525

    
526
if ($input_errors) {
527
	print_input_errors($input_errors);
528
}
529

    
530
if ($savemsg) {
531
	print_info_box($savemsg, 'success');
532
}
533

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

    
538
/* active tabs */
539
$tab_array = array();
540
$tabscounter = 0;
541
$i = 0;
542

    
543
foreach ($iflist as $ifent => $ifname) {
544
	$oc = $config['interfaces'][$ifent];
545
	$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
546
	    (is_ipaddrv6($oc['ipaddrv6']) &&
547
	    !is_linklocal($oc['ipaddrv6'])));
548

    
549
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
550
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
551
	    !$valid_if_ipaddrv6) {
552
		continue;
553
	}
554

    
555
	if ($ifent == $if) {
556
		$active = true;
557
	} else {
558
		$active = false;
559
	}
560

    
561
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
562
	$tabscounter++;
563
}
564

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

    
573
			if ($ifent == $if) {
574
				$active = true;
575
			} else {
576
				$active = false;
577
			}
578

    
579
			$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
580
			$tabscounter++;
581
		}
582
	}
583
}
584

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

    
591
display_top_tabs($tab_array);
592

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

    
598
$form = new Form();
599

    
600
$section = new Form_Section('DHCPv6 Options');
601

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

    
618
if (is_ipaddrv6($ifcfgip)) {
619

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

    
630
	$section->addInput(new Form_StaticText(
631
		'Subnet Mask',
632
		$ifcfgsn . ' bits'
633
		));
634

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

    
641
if ($is_olsr_enabled) {
642
	$section->addInput(new Form_Select(
643
	'netmask',
644
	'Subnet Mask',
645
	$pconfig['netmask'],
646
	array_combine(range(128, 1, -1), range(128, 1, -1))
647
	));
648
}
649

    
650
$f1 = new Form_Input(
651
	'range_from',
652
	null,
653
	'text',
654
	$pconfig['range_from']
655
);
656

    
657
$f1->setHelp('From');
658

    
659
$f2 = new Form_Input(
660
	'range_to',
661
	null,
662
	'text',
663
	$pconfig['range_to']
664
);
665

    
666
$f2->setHelp('To');
667

    
668
$group = new Form_Group('*Range');
669

    
670
$group->add($f1);
671
$group->add($f2);
672

    
673
$section->add($group);
674

    
675
$f1 = new Form_Input(
676
	'prefixrange_from',
677
	null,
678
	'text',
679
	$pconfig['prefixrange_from']
680
);
681

    
682
$f1->setHelp('From');
683

    
684
$f2 = new Form_Input(
685
	'prefixrange_to',
686
	null,
687
	'text',
688
	$pconfig['prefixrange_to']
689
);
690

    
691
$f2->setHelp('To');
692

    
693
$group = new Form_Group('Prefix Delegation Range');
694

    
695
$group->add($f1);
696
$group->add($f2);
697

    
698
$section->add($group);
699

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

    
717
$group = new Form_Group('DNS Servers');
718

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

    
729
$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.');
730
$section->add($group);
731

    
732
$section->addInput(new Form_Input(
733
	'domain',
734
	'Domain name',
735
	'text',
736
	$pconfig['domain']
737
))->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. ');
738

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

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

    
754
$section->addInput(new Form_Input(
755
	'maxtime',
756
	'Max lease time',
757
	'text',
758
	$pconfig['maxtime']
759
))->setHelp('Maximum lease time for clients that ask for a specific expiration time.' . ' <br />' .
760
			'The default is 86400 seconds.');
761

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

    
771
$btnadv = new Form_Button(
772
	'btnadvdns',
773
	'Display Advanced',
774
	null,
775
	'fa-cog'
776
);
777

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

    
780
$section->addInput(new Form_StaticText(
781
	'Dynamic DNS',
782
	$btnadv
783
));
784

    
785
$section->addInput(new Form_Checkbox(
786
	'ddnsupdate',
787
	'DHCP Registration',
788
	'Enable registration of DHCP client names in DNS.',
789
	$pconfig['ddnsupdate']
790
));
791

    
792
$section->addInput(new Form_Input(
793
	'ddnsdomain',
794
	'DDNS Domain',
795
	'text',
796
	$pconfig['ddnsdomain']
797
))->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.');
798

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

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

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

    
820
$section->addInput(new Form_Input(
821
	'ddnsdomainkey',
822
	'DDNS Domain Key secret',
823
	'text',
824
	$pconfig['ddnsdomainkey']
825
))->setHelp('Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.');
826

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

    
840
$section->addInput(new Form_Checkbox(
841
	'ddnsreverse',
842
	'DDNS Reverse',
843
	'Add reverse dynamic DNS entries.',
844
	$pconfig['ddnsreverse']
845
));
846

    
847
$btnadv = new Form_Button(
848
	'btnadvntp',
849
	'Display Advanced',
850
	null,
851
	'fa-cog'
852
);
853

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

    
856
$section->addInput(new Form_StaticText(
857
	'NTP servers',
858
	$btnadv
859
));
860

    
861
$group = new Form_Group('NTP Servers');
862

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

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

    
879
$group->addClass('ntpclass');
880

    
881
$section->add($group);
882

    
883
$btnadv = new Form_Button(
884
	'btnadvldap',
885
	'Display Advanced',
886
	null,
887
	'fa-cog'
888
);
889

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

    
892
$section->addInput(new Form_StaticText(
893
	'LDAP',
894
	$btnadv
895
));
896

    
897
$section->addInput(new Form_Input(
898
	'ldap',
899
	'LDAP URI',
900
	'text',
901
	$pconfig['ldap']
902
));
903

    
904
$btnadv = new Form_Button(
905
	'btnadvnetboot',
906
	'Display Advanced',
907
	null,
908
	'fa-cog'
909
);
910

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

    
913
$section->addInput(new Form_StaticText(
914
	'Network booting',
915
	$btnadv
916
));
917

    
918
$section->addInput(new Form_Checkbox(
919
	'shownetboot',
920
	'Network booting',
921
	'Enable Network Booting',
922
	$pconfig['shownetboot']
923
));
924

    
925
$section->addInput(new Form_Input(
926
	'bootfile_url',
927
	'Bootfile URL',
928
	'text',
929
	$pconfig['bootfile_url']
930
));
931

    
932
$btnadv = new Form_Button(
933
	'btnadvopts',
934
	'Display Advanced',
935
	null,
936
	'fa-cog'
937
);
938

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

    
941
$section->addInput(new Form_StaticText(
942
	'Additional BOOTP/DHCP Options',
943
	$btnadv
944
));
945

    
946
$form->add($section);
947

    
948
$title = 'Show Additional BOOTP/DHCP Options';
949

    
950
if (!$pconfig['numberoptions']) {
951
	$noopts = true;
952
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
953
} else {
954
	$noopts = false;
955
}
956

    
957
$counter = 0;
958
$last = count($pconfig['numberoptions']['item']) - 1;
959

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

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

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

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

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

    
992

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

    
1000
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
1001

    
1002
$section->addInput($btnaddopt);
1003

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

    
1011
print($form);
1012

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

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

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

    
1091
	// Show advanced DNS options ======================================================================================
1092
	var showadvdns = false;
1093

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

    
1118
		hideCheckbox('ddnsupdate', !showadvdns);
1119
		hideInput('ddnsdomain', !showadvdns);
1120
		hideCheckbox('ddnsforcehostname', !showadvdns);
1121
		hideInput('ddnsdomainprimary', !showadvdns);
1122
		hideInput('ddnsdomainkeyname', !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['shownetboot'] && 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('shownetboot', !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');
(120-120/225)