Project

General

Profile

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

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

    
67
require("guiconfig.inc");
68
require_once("filter.inc");
69

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

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

    
111
/*	Fix failover DHCP problem
112
 *	http://article.gmane.org/gmane.comp.security.firewalls.pfsense.support/18749
113
 */
114
ini_set("memory_limit", "64M");
115

    
116
$if = $_GET['if'];
117
if ($_POST['if']) {
118
	$if = $_POST['if'];
119
}
120

    
121
/* if OLSRD is enabled, allow WAN to house DHCP. */
122
if ($config['installedpackages']['olsrd']) {
123
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
124
		if ($olsrd['enable']) {
125
			$is_olsr_enabled = true;
126
			break;
127
		}
128
	}
129
}
130

    
131
$iflist = get_configured_interface_with_descr();
132
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
133

    
134
/* set the starting interface */
135
if (!$if || !isset($iflist[$if])) {
136
	foreach ($iflist as $ifent => $ifname) {
137
		$oc = $config['interfaces'][$ifent];
138
		$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
139
		    (is_ipaddrv6($oc['ipaddrv6']) &&
140
		    !is_linklocal($oc['ipaddrv6'])));
141

    
142
		if ((!is_array($config['dhcpdv6'][$ifent]) ||
143
		    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
144
		    !$valid_if_ipaddrv6) {
145
			continue;
146
		}
147
		$if = $ifent;
148
		break;
149
	}
150
}
151

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

    
191
if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
192
	$trackifname = $config['interfaces'][$if]['track6-interface'];
193
	$trackcfg = $config['interfaces'][$trackifname];
194
	$ifcfgsn = "64";
195
	$ifcfgip = '::';
196

    
197
	$str_help_mask = dhcpv6_pd_str_help($ifcfgsn);
198
} else {
199
	$ifcfgip = get_interface_ipv6($if);
200
	$ifcfgsn = get_interface_subnetv6($if);
201
}
202

    
203
/*	 set the enabled flag which will tell us if DHCP relay is enabled
204
 *	 on any interface. We will use this to disable DHCP server since
205
 *	 the two are not compatible with each other.
206
 */
207

    
208
$dhcrelay_enabled = false;
209
$dhcrelaycfg = $config['dhcrelay6'];
210

    
211
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
212
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
213

    
214
	foreach ($dhcrelayifs as $dhcrelayif) {
215

    
216
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
217
			$dhcrelay_enabled = true;
218
			break;
219
		}
220
	}
221
}
222

    
223
if (isset($_POST['apply'])) {
224
	$savemsg = dhcpv6_apply_changes(false);
225
} elseif (isset($_POST['save'])) {
226
	unset($input_errors);
227

    
228
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
229
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
230
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
231

    
232
	$pconfig = $_POST;
233

    
234
	$numberoptions = array();
235
	for ($x = 0; $x < 99; $x++) {
236
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
237
			$numbervalue = array();
238
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
239
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
240
			$numberoptions['item'][] = $numbervalue;
241
		}
242
	}
243
	// Reload the new pconfig variable that the forum uses.
244
	$pconfig['numberoptions'] = $numberoptions;
245

    
246
	/* input validation */
247
	if ($_POST['enable']) {
248
		$reqdfields = explode(" ", "range_from range_to");
249
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
250

    
251
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
252

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

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

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

    
273
			$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
274
			    $_POST['prefixrange_length']);
275
			$netmask = Net_IPv6::compress($netmask);
276

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

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

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

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

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

    
365
		$noip = false;
366
		if (is_array($a_maps)) {
367
			foreach ($a_maps as $map) {
368
				if (empty($map['ipaddrv6'])) {
369
					$noip = true;
370
				}
371
			}
372
		}
373
		if (!$input_errors) {
374
			/* make sure the range lies within the current subnet */
375
			$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
376
			$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
377

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

    
389
			/* make sure that the DHCP Relay isn't enabled on this interface */
390
			if (isset($config['dhcrelay'][$if]['enable'])) {
391
				$input_errors[] = sprintf(gettext("The DHCP relay on the %s interface must be disabled before enabling the DHCP server."), $iflist[$if]);
392
			}
393

    
394

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

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

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

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

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

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

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

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

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

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

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

    
484
		write_config();
485

    
486
		$savemsg = dhcpv6_apply_changes($dhcpdv6_enable_changed);
487
	}
488
}
489

    
490
if ($_GET['act'] == "del") {
491
	if ($a_maps[$_GET['id']]) {
492
		unset($a_maps[$_GET['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

    
507
if (!empty($if) && isset($iflist[$if])) {
508
	$pgtitle[] = $iflist[$if];
509
	$pgtitle[] = gettext("DHCPv6 Server");
510
}
511
$shortcut_section = "dhcp6";
512

    
513
include("head.inc");
514

    
515
if ($input_errors) {
516
	print_input_errors($input_errors);
517
}
518

    
519
if ($savemsg) {
520
	print_info_box($savemsg, 'success');
521
}
522

    
523
if ($dhcrelay_enabled) {
524
	print_info_box(gettext("DHCPv6 Relay is currently enabled. Cannot enable the DHCPv6 Server service while the DHCPv6 Relay is enabled on any interface."), 'danger', false);
525
}
526

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

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

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

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

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

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

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

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

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

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

    
584
display_top_tabs($tab_array);
585

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

    
591
if ($dhcrelay_enabled) {
592
	include("foot.inc");
593
	exit;
594
}
595

    
596
$form = new Form();
597

    
598
$section = new Form_Section('DHCPv6 Options');
599

    
600
$section->addInput(new Form_Checkbox(
601
	'enable',
602
	'DHCPv6 Server',
603
	'Enable DHCPv6 server on interface ' . $iflist[$if],
604
	$pconfig['enable']
605
));
606

    
607
if (is_ipaddrv6($ifcfgip)) {
608

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

    
619
	$section->addInput(new Form_StaticText(
620
		'Subnet Mask',
621
		$ifcfgsn . ' bits'
622
		));
623

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

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

    
639
$f1 = new Form_Input(
640
	'range_from',
641
	null,
642
	'text',
643
	$pconfig['range_from']
644
);
645

    
646
$f1->setHelp('From');
647

    
648
$f2 = new Form_Input(
649
	'range_to',
650
	null,
651
	'text',
652
	$pconfig['range_to']
653
);
654

    
655
$f2->setHelp('To');
656

    
657
$group = new Form_Group('Range');
658

    
659
$group->add($f1);
660
$group->add($f2);
661

    
662
$section->add($group);
663

    
664
$f1 = new Form_Input(
665
	'prefixrange_from',
666
	null,
667
	'text',
668
	$pconfig['prefixrange_from']
669
);
670

    
671
$f1->setHelp('From');
672

    
673
$f2 = new Form_Input(
674
	'prefixrange_to',
675
	null,
676
	'text',
677
	$pconfig['prefixrange_to']
678
);
679

    
680
$f2->setHelp('To');
681

    
682
$group = new Form_Group('Prefix Delegation Range');
683

    
684
$group->add($f1);
685
$group->add($f2);
686

    
687
$section->add($group);
688

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

    
704
$group = new Form_Group('DNS Servers');
705

    
706
for ($i=1;$i<=4; $i++) {
707
	$group->add(new Form_input(
708
		'dns' . $i,
709
		null,
710
		'text',
711
		$pconfig['dns' . $i],
712
		['placeholder' => 'DNS ' . $i]
713
	));
714
}
715

    
716
$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.');
717
$section->add($group);
718

    
719
$section->addInput(new Form_Input(
720
	'domain',
721
	'Domain Name',
722
	'text',
723
	$pconfig['domain']
724
))->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. ');
725

    
726
$section->addInput(new Form_Input(
727
	'domainsearchlist',
728
	'Domain search list',
729
	'text',
730
	$pconfig['domainsearchlist']
731
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator');
732

    
733
$section->addInput(new Form_Input(
734
	'deftime',
735
	'Default lease time',
736
	'text',
737
	$pconfig['deftime']
738
))->setHelp('Lease time in seconds. Used for clients that do not ask for a specific expiration time. ' . ' <br />' .
739
			'The default is 7200 seconds.');
740

    
741
$section->addInput(new Form_Input(
742
	'maxtime',
743
	'Max lease time',
744
	'text',
745
	$pconfig['maxtime']
746
))->setHelp('Maximum lease time for clients that ask for a specific expiration time.' . ' <br />' .
747
			'The default is 86400 seconds.');
748

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

    
758
$btnadv = new Form_Button(
759
	'btnadvdns',
760
	'Display Advanced',
761
	null,
762
	'fa-cog'
763
);
764

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

    
767
$section->addInput(new Form_StaticText(
768
	'Dynamic DNS',
769
	$btnadv
770
));
771

    
772
$section->addInput(new Form_Checkbox(
773
	'ddnsupdate',
774
	'DHCP Registration',
775
	'Enable registration of DHCP client names in DNS.',
776
	$pconfig['ddnsupdate']
777
));
778

    
779
$section->addInput(new Form_Input(
780
	'ddnsdomain',
781
	'DDNS Domain',
782
	'text',
783
	$pconfig['ddnsdomain']
784
))->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.');
785

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

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

    
799
$section->addInput(new Form_Input(
800
	'ddnsdomainkey',
801
	'DDNS Domain Key secret',
802
	'text',
803
	$pconfig['ddnsdomainkey']
804
))->setHelp('Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.');
805

    
806
$section->addInput(new Form_Select(
807
	'ddnsclientupdates',
808
	'DDNS Client Updates',
809
	$pconfig['ddnsclientupdates'],
810
	array(
811
	    'allow' => gettext('Allow'),
812
	    'deny' => gettext('Deny'),
813
	    'ignore' => gettext('Ignore'))
814
))->setHelp('How Forward entries are handled when client indicates they wish to update DNS.  ' .
815
	    'Allow prevents DHCP from updating Forward entries, Deny indicates that DHCP will ' .
816
	    'do the updates and the client should not, Ignore specifies that DHCP will do the ' .
817
	    'update and the client can also attempt the update usually using a different domain name.');
818

    
819
$section->addInput(new Form_Checkbox(
820
	'ddnsreverse',
821
	'DDNS Reverse',
822
	'Add reverse dynamic DNS entries.',
823
	$pconfig['ddnsreverse']
824
));
825

    
826
$btnadv = new Form_Button(
827
	'btnadvntp',
828
	'Display Advanced',
829
	null,
830
	'fa-cog'
831
);
832

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

    
835
$section->addInput(new Form_StaticText(
836
	'NTP servers',
837
	$btnadv
838
));
839

    
840
$group = new Form_Group('NTP Servers');
841

    
842
$group->add(new Form_Input(
843
	'ntp1',
844
	'NTP Server 1',
845
	'text',
846
	$pconfig['ntp1'],
847
	['placeholder' => 'NTP 1']
848
));
849

    
850
$group->add(new Form_Input(
851
	'ntp2',
852
	'NTP Server 2',
853
	'text',
854
	$pconfig['ntp2'],
855
	['placeholder' => 'NTP 2']
856
));
857

    
858
$group->addClass('ntpclass');
859

    
860
$section->add($group);
861

    
862
$btnadv = new Form_Button(
863
	'btnadvldap',
864
	'Display Advanced',
865
	null,
866
	'fa-cog'
867
);
868

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

    
871
$section->addInput(new Form_StaticText(
872
	'LDAP',
873
	$btnadv
874
));
875

    
876
$section->addInput(new Form_Input(
877
	'ldap',
878
	'LDAP URI',
879
	'text',
880
	$pconfig['ldap']
881
));
882

    
883
$btnadv = new Form_Button(
884
	'btnadvnetboot',
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
	'Network booting',
894
	$btnadv
895
));
896

    
897
$section->addInput(new Form_Checkbox(
898
	'shownetboot',
899
	'Network booting',
900
	'Enable Network Booting',
901
	$pconfig['shownetboot']
902
));
903

    
904
$section->addInput(new Form_Input(
905
	'bootfile_url',
906
	'Bootfile URL',
907
	'text',
908
	$pconfig['bootfile_url']
909
));
910

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

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

    
920
$section->addInput(new Form_StaticText(
921
	'Additional BOOTP/DHCP Options',
922
	$btnadv
923
));
924

    
925
$form->add($section);
926

    
927
$title = 'Show Additional BOOTP/DHCP Options';
928

    
929
if (!$pconfig['numberoptions']) {
930
	$noopts = true;
931
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
932
} else {
933
	$noopts = false;
934
}
935

    
936
$counter = 0;
937
$last = count($pconfig['numberoptions']['item']) - 1;
938

    
939
foreach ($pconfig['numberoptions']['item'] as $item) {
940
	$group = new Form_Group(null);
941
	$group->addClass('repeatable');
942
	$group->addClass('adnloptions');
943

    
944
	$group->add(new Form_Input(
945
		'number' . $counter,
946
		null,
947
		'text',
948
		$item['number']
949
	))->setHelp($counter == $last ? 'Number':null);
950

    
951
	$group->add(new Form_Input(
952
		'value' . $counter,
953
		null,
954
		'text',
955
		base64_decode($item['value'])
956
	))->setHelp($counter == $last ? 'Value':null);
957

    
958
	$btn = new Form_Button(
959
		'deleterow' . $counter,
960
		'Delete',
961
		null,
962
		'fa-trash'
963
	);
964

    
965
	$btn->addClass('btn-warning');
966
	$group->add($btn);
967
	$section->add($group);
968
	$counter++;
969
}
970

    
971

    
972
$btnaddopt = new Form_Button(
973
	'addrow',
974
	'Add Option',
975
	null,
976
	'fa-plus'
977
);
978

    
979
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
980

    
981
$section->addInput($btnaddopt);
982

    
983
$section->addInput(new Form_Input(
984
	'if',
985
	null,
986
	'hidden',
987
	$if
988
));
989

    
990
print($form);
991

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

    
1059
<nav class="action-buttons">
1060
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1061
		<i class="fa fa-plus icon-embed-btn"></i>
1062
		<?=gettext("Add")?>
1063
	</a>
1064
</nav>
1065

    
1066
<script type="text/javascript">
1067
//<![CDATA[
1068
events.push(function() {
1069

    
1070
	// Show advanced DNS options ======================================================================================
1071
	var showadvdns = false;
1072

    
1073
	function show_advdns(ispageload) {
1074
		var text;
1075
		// On page load decide the initial state based on the data.
1076
		if (ispageload) {
1077
<?php
1078
			if (!$pconfig['ddnsupdate'] &&
1079
			    empty($pconfig['ddnsdomain']) &&
1080
			    empty($pconfig['ddnsdomainprimary']) &&
1081
			    empty($pconfig['ddnsdomainkeyname']) &&
1082
			    empty($pconfig['ddnsdomainkey']) &&
1083
			    (empty($pconfig['ddnsclientupdates']) || ($pconfig['ddnsclientupdates'] == "allow")) &&
1084
			    !$pconfig['ddnsreverse']) {
1085
				$showadv = false;
1086
			} else {
1087
				$showadv = true;
1088
			}
1089
?>
1090
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1091
		} else {
1092
			// It was a click, swap the state.
1093
			showadvdns = !showadvdns;
1094
		}
1095

    
1096
		hideCheckbox('ddnsupdate', !showadvdns);
1097
		hideInput('ddnsdomain', !showadvdns);
1098
		hideInput('ddnsdomainprimary', !showadvdns);
1099
		hideInput('ddnsdomainkeyname', !showadvdns);
1100
		hideInput('ddnsdomainkey', !showadvdns);
1101
		hideInput('ddnsclientupdates', !showadvdns);
1102
		hideCheckbox('ddnsreverse', !showadvdns);
1103

    
1104
		if (showadvdns) {
1105
			text = "<?=gettext('Hide Advanced');?>";
1106
		} else {
1107
			text = "<?=gettext('Display Advanced');?>";
1108
		}
1109
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1110
	}
1111

    
1112
	$('#btnadvdns').click(function(event) {
1113
		show_advdns();
1114
	});
1115

    
1116
	// Show advanced NTP options ======================================================================================
1117
	var showadvntp = false;
1118

    
1119
	function show_advntp(ispageload) {
1120
		var text;
1121
		// On page load decide the initial state based on the data.
1122
		if (ispageload) {
1123
<?php
1124
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1125
				$showadv = false;
1126
			} else {
1127
				$showadv = true;
1128
			}
1129
?>
1130
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1131
		} else {
1132
			// It was a click, swap the state.
1133
			showadvntp = !showadvntp;
1134
		}
1135

    
1136
		hideInput('ntp1', !showadvntp);
1137
		hideInput('ntp2', !showadvntp);
1138

    
1139
		if (showadvntp) {
1140
			text = "<?=gettext('Hide Advanced');?>";
1141
		} else {
1142
			text = "<?=gettext('Display Advanced');?>";
1143
		}
1144
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1145
	}
1146

    
1147
	$('#btnadvntp').click(function(event) {
1148
		show_advntp();
1149
	});
1150

    
1151
	// Show advanced LDAP options ======================================================================================
1152
	var showadvldap = false;
1153

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

    
1171
		hideInput('ldap', !showadvldap);
1172

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

    
1181
	$('#btnadvldap').click(function(event) {
1182
		show_advldap();
1183
	});
1184

    
1185
	// Show advanced Netboot options ======================================================================================
1186
	var showadvnetboot = false;
1187

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

    
1205
		hideCheckbox('shownetboot', !showadvnetboot);
1206
		hideInput('bootfile_url', !showadvnetboot);
1207

    
1208
		if (showadvnetboot) {
1209
			text = "<?=gettext('Hide Advanced');?>";
1210
		} else {
1211
			text = "<?=gettext('Display Advanced');?>";
1212
		}
1213
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1214
	}
1215

    
1216
	$('#btnadvnetboot').click(function(event) {
1217
		show_advnetboot();
1218
	});
1219

    
1220
	// Show advanced additional opts options ===========================================================================
1221
	var showadvopts = false;
1222

    
1223
	function show_advopts(ispageload) {
1224
		var text;
1225
		// On page load decide the initial state based on the data.
1226
		if (ispageload) {
1227
<?php
1228
			if (empty($pconfig['numberoptions']) ||
1229
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1230
				$showadv = false;
1231
			} else {
1232
				$showadv = true;
1233
			}
1234
?>
1235
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1236
		} else {
1237
			// It was a click, swap the state.
1238
			showadvopts = !showadvopts;
1239
		}
1240

    
1241
		hideClass('adnloptions', !showadvopts);
1242
		hideInput('addrow', !showadvopts);
1243

    
1244
		if (showadvopts) {
1245
			text = "<?=gettext('Hide Advanced');?>";
1246
		} else {
1247
			text = "<?=gettext('Display Advanced');?>";
1248
		}
1249
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1250
	}
1251

    
1252
	$('#btnadvopts').click(function(event) {
1253
		show_advopts();
1254
		checkLastRow();
1255
	});
1256

    
1257
	$('#enable').click(function() {
1258
	    do_toggle();
1259
	});
1260

    
1261
	function do_toggle() {
1262
		if ($('#enable').prop('checked')) {
1263
			$('.form-group:not(:first-child)').show();
1264
			hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1265
			hideInput('addrow', <?php echo json_encode($noopts); ?>);
1266
		} else {
1267
			$('.form-group:not(:first-child)').hide();
1268
		}
1269
	}
1270

    
1271
	// On initial load
1272
	do_toggle();
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');
(121-121/225)