Project

General

Profile

Download (37.8 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
/*	Fix failover DHCP problem
111
 *	http://article.gmane.org/gmane.comp.security.firewalls.pfsense.support/18749
112
 */
113
ini_set("memory_limit", "64M");
114

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

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

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

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

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

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

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

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

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

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

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

    
213
	foreach ($dhcrelayifs as $dhcrelayif) {
214

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

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

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

    
231
	$pconfig = $_POST;
232

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
393

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

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

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

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

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

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

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

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

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

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

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

    
483
		write_config();
484

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

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

    
504
$pgtitle = array(gettext("Services"), htmlspecialchars(gettext("DHCPv6 Server & RA")));
505

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

    
512
include("head.inc");
513

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

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

    
522
if ($dhcrelay_enabled) {
523
	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);
524
}
525

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

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

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

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

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

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

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

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

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

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

    
583
display_top_tabs($tab_array);
584

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

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

    
595
$form = new Form();
596

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

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

    
606
if (is_ipaddrv6($ifcfgip)) {
607

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
891
$section->addInput(new Form_StaticText(
892
	'Network booting',
893
	$btnadv
894
));
895

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
970

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

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

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

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

    
989
print($form);
990

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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