Project

General

Profile

Download (37.7 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 Electric Sheep Fencing, LLC
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['ddnsreverse'] = isset($config['dhcpdv6'][$if]['ddnsreverse']);
170
	$pconfig['ddnsclientupdates'] = $config['dhcpdv6'][$if]['ddnsclientupdates'];
171
	list($pconfig['ntp1'], $pconfig['ntp2']) = $config['dhcpdv6'][$if]['ntpserver'];
172
	$pconfig['tftp'] = $config['dhcpdv6'][$if]['tftp'];
173
	$pconfig['ldap'] = $config['dhcpdv6'][$if]['ldap'];
174
	$pconfig['netboot'] = isset($config['dhcpdv6'][$if]['netboot']);
175
	$pconfig['bootfile_url'] = $config['dhcpdv6'][$if]['bootfile_url'];
176
	$pconfig['netmask'] = $config['dhcpdv6'][$if]['netmask'];
177
	$pconfig['numberoptions'] = $config['dhcpdv6'][$if]['numberoptions'];
178
	$pconfig['dhcpv6leaseinlocaltime'] = $config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'];
179
	if (!is_array($config['dhcpdv6'][$if]['staticmap'])) {
180
		$config['dhcpdv6'][$if]['staticmap'] = array();
181
	}
182
	$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
183
}
184

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

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

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

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

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

    
208
	foreach ($dhcrelayifs as $dhcrelayif) {
209

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

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

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

    
226
	$pconfig = $_POST;
227

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

    
240
	/* input validation */
241
	if ($_POST['enable']) {
242
		$reqdfields = explode(" ", "range_from range_to");
243
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
244

    
245
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
246

    
247
		if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
248
			$input_errors[] = gettext("A valid prefix range must be specified.");
249
		}
250
		if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
251
			$input_errors[] = gettext("A valid prefix range must be specified.");
252
		}
253

    
254
		if ($_POST['prefixrange_from'] && $_POST['prefixrange_to'] &&
255
		    $_POST['prefixrange_length']) {
256
			$netmask = Net_IPv6::getNetmask($_POST['prefixrange_from'],
257
			    $_POST['prefixrange_length']);
258
			$netmask = Net_IPv6::compress($netmask);
259

    
260
			if ($netmask != Net_IPv6::compress(strtolower(
261
			    $_POST['prefixrange_from']))) {
262
				$input_errors[] = sprintf(gettext(
263
				    "Prefix Delegation From address is not a valid IPv6 Netmask for %s"),
264
				    $netmask . '/' . $_POST['prefixrange_length']);
265
			}
266

    
267
			$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
268
			    $_POST['prefixrange_length']);
269
			$netmask = Net_IPv6::compress($netmask);
270

    
271
			if ($netmask != Net_IPv6::compress(strtolower(
272
			    $_POST['prefixrange_to']))) {
273
				$input_errors[] = sprintf(gettext(
274
				    "Prefix Delegation To address is not a valid IPv6 Netmask for %s"),
275
				    $netmask . '/' . $_POST['prefixrange_length']);
276
			}
277
		}
278

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

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

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

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

    
359
		$noip = false;
360
		if (is_array($a_maps)) {
361
			foreach ($a_maps as $map) {
362
				if (empty($map['ipaddrv6'])) {
363
					$noip = true;
364
				}
365
			}
366
		}
367
		if (!$input_errors) {
368
			/* make sure the range lies within the current subnet */
369
			$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
370
			$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
371

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

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

    
388

    
389
			/* Verify static mappings do not overlap:
390
			   - available DHCP range
391
			   - prefix delegation range (FIXME: still need to be completed) */
392
			$dynsubnet_start = inet_pton($_POST['range_from']);
393
			$dynsubnet_end = inet_pton($_POST['range_to']);
394

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

    
410
	if (!$input_errors) {
411
		if (!is_array($config['dhcpdv6'][$if])) {
412
			$config['dhcpdv6'][$if] = array();
413
		}
414
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
415
			$config['dhcpdv6'][$if]['range'] = array();
416
		}
417
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
418
			$config['dhcpdv6'][$if]['prefixrange'] = array();
419
		}
420

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

    
430
		unset($config['dhcpdv6'][$if]['winsserver']);
431

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

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

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

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

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

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

    
478
		write_config();
479

    
480
		$savemsg = dhcpv6_apply_changes($dhcpdv6_enable_changed);
481
	}
482
}
483

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

    
501
if (!empty($if) && isset($iflist[$if])) {
502
	$pgtitle[] = $iflist[$if];
503
	$pgtitle[] = gettext("DHCPv6 Server");
504
}
505
$shortcut_section = "dhcp6";
506

    
507
include("head.inc");
508

    
509
if ($input_errors) {
510
	print_input_errors($input_errors);
511
}
512

    
513
if ($savemsg) {
514
	print_info_box($savemsg, 'success');
515
}
516

    
517
if ($dhcrelay_enabled) {
518
	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);
519
}
520

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

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

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

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

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

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

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

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

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

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

    
578
display_top_tabs($tab_array);
579

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

    
585
if ($dhcrelay_enabled) {
586
	include("foot.inc");
587
	exit;
588
}
589

    
590
$form = new Form();
591

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

    
594
$section->addInput(new Form_Checkbox(
595
	'enable',
596
	'DHCPv6 Server',
597
	'Enable DHCPv6 server on interface ' . $iflist[$if],
598
	$pconfig['enable']
599
));
600

    
601
if (is_ipaddrv6($ifcfgip)) {
602

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

    
613
	$section->addInput(new Form_StaticText(
614
		'Subnet Mask',
615
		$ifcfgsn . ' bits'
616
		));
617

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

    
624
if ($is_olsr_enabled) {
625
	$section->addInput(new Form_Select(
626
	'netmask',
627
	'Subnet Mask',
628
	$pconfig['netmask'],
629
	array_combine(range(128, 1, -1), range(128, 1, -1))
630
	));
631
}
632

    
633
$f1 = new Form_Input(
634
	'range_from',
635
	null,
636
	'text',
637
	$pconfig['range_from']
638
);
639

    
640
$f1->setHelp('From');
641

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

    
649
$f2->setHelp('To');
650

    
651
$group = new Form_Group('Range');
652

    
653
$group->add($f1);
654
$group->add($f2);
655

    
656
$section->add($group);
657

    
658
$f1 = new Form_Input(
659
	'prefixrange_from',
660
	null,
661
	'text',
662
	$pconfig['prefixrange_from']
663
);
664

    
665
$f1->setHelp('From');
666

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

    
674
$f2->setHelp('To');
675

    
676
$group = new Form_Group('Prefix Delegation Range');
677

    
678
$group->add($f1);
679
$group->add($f2);
680

    
681
$section->add($group);
682

    
683
$section->addInput(new Form_Select(
684
	'prefixrange_length',
685
	'Prefix Delegation Size',
686
	$pconfig['prefixrange_length'],
687
	array(
688
		'48' => '48',
689
		'52' => '52',
690
		'56' => '56',
691
		'60' => '60',
692
		'62' => '62',
693
		'63' => '63',
694
		'64' => '64'
695
		)
696
))->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.');
697

    
698
$group = new Form_Group('DNS Servers');
699

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

    
710
$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.');
711
$section->add($group);
712

    
713
$section->addInput(new Form_Input(
714
	'domain',
715
	'Domain name',
716
	'text',
717
	$pconfig['domain']
718
))->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. ');
719

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

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

    
735
$section->addInput(new Form_Input(
736
	'maxtime',
737
	'Max lease time',
738
	'text',
739
	$pconfig['maxtime']
740
))->setHelp('Maximum lease time for clients that ask for a specific expiration time.' . ' <br />' .
741
			'The default is 86400 seconds.');
742

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

    
752
$btnadv = new Form_Button(
753
	'btnadvdns',
754
	'Display Advanced',
755
	null,
756
	'fa-cog'
757
);
758

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

    
761
$section->addInput(new Form_StaticText(
762
	'Dynamic DNS',
763
	$btnadv
764
));
765

    
766
$section->addInput(new Form_Checkbox(
767
	'ddnsupdate',
768
	'DHCP Registration',
769
	'Enable registration of DHCP client names in DNS.',
770
	$pconfig['ddnsupdate']
771
));
772

    
773
$section->addInput(new Form_Input(
774
	'ddnsdomain',
775
	'DDNS Domain',
776
	'text',
777
	$pconfig['ddnsdomain']
778
))->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.');
779

    
780
$section->addInput(new Form_IpAddress(
781
	'ddnsdomainprimary',
782
	'DDNS Server IP',
783
	$pconfig['ddnsdomainprimary']
784
))->setHelp('Enter the primary domain name server IP address for the dynamic domain name.');
785

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

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

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

    
813
$section->addInput(new Form_Checkbox(
814
	'ddnsreverse',
815
	'DDNS Reverse',
816
	'Add reverse dynamic DNS entries.',
817
	$pconfig['ddnsreverse']
818
));
819

    
820
$btnadv = new Form_Button(
821
	'btnadvntp',
822
	'Display Advanced',
823
	null,
824
	'fa-cog'
825
);
826

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

    
829
$section->addInput(new Form_StaticText(
830
	'NTP servers',
831
	$btnadv
832
));
833

    
834
$group = new Form_Group('NTP Servers');
835

    
836
$group->add(new Form_Input(
837
	'ntp1',
838
	'NTP Server 1',
839
	'text',
840
	$pconfig['ntp1'],
841
	['placeholder' => 'NTP 1']
842
));
843

    
844
$group->add(new Form_Input(
845
	'ntp2',
846
	'NTP Server 2',
847
	'text',
848
	$pconfig['ntp2'],
849
	['placeholder' => 'NTP 2']
850
));
851

    
852
$group->addClass('ntpclass');
853

    
854
$section->add($group);
855

    
856
$btnadv = new Form_Button(
857
	'btnadvldap',
858
	'Display Advanced',
859
	null,
860
	'fa-cog'
861
);
862

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

    
865
$section->addInput(new Form_StaticText(
866
	'LDAP',
867
	$btnadv
868
));
869

    
870
$section->addInput(new Form_Input(
871
	'ldap',
872
	'LDAP URI',
873
	'text',
874
	$pconfig['ldap']
875
));
876

    
877
$btnadv = new Form_Button(
878
	'btnadvnetboot',
879
	'Display Advanced',
880
	null,
881
	'fa-cog'
882
);
883

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

    
886
$section->addInput(new Form_StaticText(
887
	'Network booting',
888
	$btnadv
889
));
890

    
891
$section->addInput(new Form_Checkbox(
892
	'shownetboot',
893
	'Network booting',
894
	'Enable Network Booting',
895
	$pconfig['shownetboot']
896
));
897

    
898
$section->addInput(new Form_Input(
899
	'bootfile_url',
900
	'Bootfile URL',
901
	'text',
902
	$pconfig['bootfile_url']
903
));
904

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

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

    
914
$section->addInput(new Form_StaticText(
915
	'Additional BOOTP/DHCP Options',
916
	$btnadv
917
));
918

    
919
$form->add($section);
920

    
921
$title = 'Show Additional BOOTP/DHCP Options';
922

    
923
if (!$pconfig['numberoptions']) {
924
	$noopts = true;
925
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
926
} else {
927
	$noopts = false;
928
}
929

    
930
$counter = 0;
931
$last = count($pconfig['numberoptions']['item']) - 1;
932

    
933
foreach ($pconfig['numberoptions']['item'] as $item) {
934
	$group = new Form_Group(null);
935
	$group->addClass('repeatable');
936
	$group->addClass('adnloptions');
937

    
938
	$group->add(new Form_Input(
939
		'number' . $counter,
940
		null,
941
		'text',
942
		$item['number']
943
	))->setHelp($counter == $last ? 'Number':null);
944

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

    
952
	$btn = new Form_Button(
953
		'deleterow' . $counter,
954
		'Delete',
955
		null,
956
		'fa-trash'
957
	);
958

    
959
	$btn->addClass('btn-warning');
960
	$group->add($btn);
961
	$section->add($group);
962
	$counter++;
963
}
964

    
965

    
966
$btnaddopt = new Form_Button(
967
	'addrow',
968
	'Add Option',
969
	null,
970
	'fa-plus'
971
);
972

    
973
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
974

    
975
$section->addInput($btnaddopt);
976

    
977
$section->addInput(new Form_Input(
978
	'if',
979
	null,
980
	'hidden',
981
	$if
982
));
983

    
984
print($form);
985

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

    
1053
<nav class="action-buttons">
1054
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1055
		<i class="fa fa-plus icon-embed-btn"></i>
1056
		<?=gettext("Add")?>
1057
	</a>
1058
</nav>
1059

    
1060
<script type="text/javascript">
1061
//<![CDATA[
1062
events.push(function() {
1063

    
1064
	// Show advanced DNS options ======================================================================================
1065
	var showadvdns = false;
1066

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

    
1090
		hideCheckbox('ddnsupdate', !showadvdns);
1091
		hideInput('ddnsdomain', !showadvdns);
1092
		hideInput('ddnsdomainprimary', !showadvdns);
1093
		hideInput('ddnsdomainkeyname', !showadvdns);
1094
		hideInput('ddnsdomainkey', !showadvdns);
1095
		hideInput('ddnsclientupdates', !showadvdns);
1096
		hideCheckbox('ddnsreverse', !showadvdns);
1097

    
1098
		if (showadvdns) {
1099
			text = "<?=gettext('Hide Advanced');?>";
1100
		} else {
1101
			text = "<?=gettext('Display Advanced');?>";
1102
		}
1103
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1104
	}
1105

    
1106
	$('#btnadvdns').click(function(event) {
1107
		show_advdns();
1108
	});
1109

    
1110
	// Show advanced NTP options ======================================================================================
1111
	var showadvntp = false;
1112

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

    
1130
		hideInput('ntp1', !showadvntp);
1131
		hideInput('ntp2', !showadvntp);
1132

    
1133
		if (showadvntp) {
1134
			text = "<?=gettext('Hide Advanced');?>";
1135
		} else {
1136
			text = "<?=gettext('Display Advanced');?>";
1137
		}
1138
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1139
	}
1140

    
1141
	$('#btnadvntp').click(function(event) {
1142
		show_advntp();
1143
	});
1144

    
1145
	// Show advanced LDAP options ======================================================================================
1146
	var showadvldap = false;
1147

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

    
1165
		hideInput('ldap', !showadvldap);
1166

    
1167
		if (showadvldap) {
1168
			text = "<?=gettext('Hide Advanced');?>";
1169
		} else {
1170
			text = "<?=gettext('Display Advanced');?>";
1171
		}
1172
		$('#btnadvldap').html('<i class="fa fa-cog"></i> ' + text);
1173
	}
1174

    
1175
	$('#btnadvldap').click(function(event) {
1176
		show_advldap();
1177
	});
1178

    
1179
	// Show advanced Netboot options ======================================================================================
1180
	var showadvnetboot = false;
1181

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

    
1199
		hideCheckbox('shownetboot', !showadvnetboot);
1200
		hideInput('bootfile_url', !showadvnetboot);
1201

    
1202
		if (showadvnetboot) {
1203
			text = "<?=gettext('Hide Advanced');?>";
1204
		} else {
1205
			text = "<?=gettext('Display Advanced');?>";
1206
		}
1207
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1208
	}
1209

    
1210
	$('#btnadvnetboot').click(function(event) {
1211
		show_advnetboot();
1212
	});
1213

    
1214
	// Show advanced additional opts options ===========================================================================
1215
	var showadvopts = false;
1216

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

    
1235
		hideClass('adnloptions', !showadvopts);
1236
		hideInput('addrow', !showadvopts);
1237

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

    
1246
	$('#btnadvopts').click(function(event) {
1247
		show_advopts();
1248
		checkLastRow();
1249
	});
1250

    
1251
	$('#enable').click(function() {
1252
	    do_toggle();
1253
	});
1254

    
1255
	function do_toggle() {
1256
		if ($('#enable').prop('checked')) {
1257
			$('.form-group:not(:first-child)').show();
1258
			hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1259
			hideInput('addrow', <?php echo json_encode($noopts); ?>);
1260
		} else {
1261
			$('.form-group:not(:first-child)').hide();
1262
		}
1263
	}
1264

    
1265
	// On initial load
1266
	do_toggle();
1267
	show_advdns(true);
1268
	show_advntp(true);
1269
	show_advldap(true);
1270
	show_advnetboot(true);
1271
	show_advopts(true);
1272
	if ($('#enable').prop('checked')) {
1273
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1274
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1275
	} else {
1276
		hideClass('adnloptions', true);
1277
		hideInput('addrow', true);
1278
	}
1279

    
1280
});
1281
//]]>
1282
</script>
1283

    
1284
<?php include('foot.inc');
(122-122/227)