Project

General

Profile

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
209
	foreach ($dhcrelayifs as $dhcrelayif) {
210

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

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

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

    
227
	$pconfig = $_POST;
228

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

    
241
	/* input validation */
242

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

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

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

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

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

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

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

    
283
	$range_from_to_ok = true;
284

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

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

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

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

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

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

    
386
	// If nothing is wrong so far, and we have range from and to, then check conditions related to the values of range from and to.
387
	if (!$input_errors && $_POST['range_from'] && $_POST['range_to']) {
388
		/* make sure the range lies within the current subnet */
389
		$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
390
		$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
391

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

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

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

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

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

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

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

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

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

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

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

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

    
492
		write_config();
493

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

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

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

    
515
if (!empty($if) && isset($iflist[$if])) {
516
	$pgtitle[] = $iflist[$if];
517
	$pgtitle[] = gettext("DHCPv6 Server");
518
}
519
$shortcut_section = "dhcp6";
520

    
521
include("head.inc");
522

    
523
if ($input_errors) {
524
	print_input_errors($input_errors);
525
}
526

    
527
if ($savemsg) {
528
	print_info_box($savemsg, 'success');
529
}
530

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

    
535
/* active tabs */
536
$tab_array = array();
537
$tabscounter = 0;
538
$i = 0;
539

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

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

    
552
	if ($ifent == $if) {
553
		$active = true;
554
	} else {
555
		$active = false;
556
	}
557

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

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

    
570
			if ($ifent == $if) {
571
				$active = true;
572
			} else {
573
				$active = false;
574
			}
575

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

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

    
588
display_top_tabs($tab_array);
589

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

    
595
$form = new Form();
596

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

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

    
615
if (is_ipaddrv6($ifcfgip)) {
616

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

    
627
	$section->addInput(new Form_StaticText(
628
		'Subnet Mask',
629
		$ifcfgsn . ' bits'
630
		));
631

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

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

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

    
654
$f1->setHelp('From');
655

    
656
$f2 = new Form_Input(
657
	'range_to',
658
	null,
659
	'text',
660
	$pconfig['range_to']
661
);
662

    
663
$f2->setHelp('To');
664

    
665
$group = new Form_Group('Range');
666

    
667
$group->add($f1);
668
$group->add($f2);
669

    
670
$section->add($group);
671

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

    
679
$f1->setHelp('From');
680

    
681
$f2 = new Form_Input(
682
	'prefixrange_to',
683
	null,
684
	'text',
685
	$pconfig['prefixrange_to']
686
);
687

    
688
$f2->setHelp('To');
689

    
690
$group = new Form_Group('Prefix Delegation Range');
691

    
692
$group->add($f1);
693
$group->add($f2);
694

    
695
$section->add($group);
696

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

    
714
$group = new Form_Group('DNS Servers');
715

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

    
726
$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.');
727
$section->add($group);
728

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

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

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

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

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

    
768
$btnadv = new Form_Button(
769
	'btnadvdns',
770
	'Display Advanced',
771
	null,
772
	'fa-cog'
773
);
774

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

    
777
$section->addInput(new Form_StaticText(
778
	'Dynamic DNS',
779
	$btnadv
780
));
781

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

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

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

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

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

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

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

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

    
844
$btnadv = new Form_Button(
845
	'btnadvntp',
846
	'Display Advanced',
847
	null,
848
	'fa-cog'
849
);
850

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

    
853
$section->addInput(new Form_StaticText(
854
	'NTP servers',
855
	$btnadv
856
));
857

    
858
$group = new Form_Group('NTP Servers');
859

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

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

    
876
$group->addClass('ntpclass');
877

    
878
$section->add($group);
879

    
880
$btnadv = new Form_Button(
881
	'btnadvldap',
882
	'Display Advanced',
883
	null,
884
	'fa-cog'
885
);
886

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

    
889
$section->addInput(new Form_StaticText(
890
	'LDAP',
891
	$btnadv
892
));
893

    
894
$section->addInput(new Form_Input(
895
	'ldap',
896
	'LDAP URI',
897
	'text',
898
	$pconfig['ldap']
899
));
900

    
901
$btnadv = new Form_Button(
902
	'btnadvnetboot',
903
	'Display Advanced',
904
	null,
905
	'fa-cog'
906
);
907

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

    
910
$section->addInput(new Form_StaticText(
911
	'Network booting',
912
	$btnadv
913
));
914

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

    
922
$section->addInput(new Form_Input(
923
	'bootfile_url',
924
	'Bootfile URL',
925
	'text',
926
	$pconfig['bootfile_url']
927
));
928

    
929
$btnadv = new Form_Button(
930
	'btnadvopts',
931
	'Display Advanced',
932
	null,
933
	'fa-cog'
934
);
935

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

    
938
$section->addInput(new Form_StaticText(
939
	'Additional BOOTP/DHCP Options',
940
	$btnadv
941
));
942

    
943
$form->add($section);
944

    
945
$title = 'Show Additional BOOTP/DHCP Options';
946

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

    
954
$counter = 0;
955
$last = count($pconfig['numberoptions']['item']) - 1;
956

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

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

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

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

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

    
989

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

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

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

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

    
1008
print($form);
1009

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

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

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

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

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

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

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

    
1132
	$('#btnadvdns').click(function(event) {
1133
		show_advdns();
1134
	});
1135

    
1136
	// Show advanced NTP options ======================================================================================
1137
	var showadvntp = false;
1138

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

    
1156
		hideInput('ntp1', !showadvntp);
1157
		hideInput('ntp2', !showadvntp);
1158

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

    
1167
	$('#btnadvntp').click(function(event) {
1168
		show_advntp();
1169
	});
1170

    
1171
	// Show advanced LDAP options ======================================================================================
1172
	var showadvldap = false;
1173

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

    
1191
		hideInput('ldap', !showadvldap);
1192

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

    
1201
	$('#btnadvldap').click(function(event) {
1202
		show_advldap();
1203
	});
1204

    
1205
	// Show advanced Netboot options ======================================================================================
1206
	var showadvnetboot = false;
1207

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

    
1225
		hideCheckbox('shownetboot', !showadvnetboot);
1226
		hideInput('bootfile_url', !showadvnetboot);
1227

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

    
1236
	$('#btnadvnetboot').click(function(event) {
1237
		show_advnetboot();
1238
	});
1239

    
1240
	// Show advanced additional opts options ===========================================================================
1241
	var showadvopts = false;
1242

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

    
1261
		hideClass('adnloptions', !showadvopts);
1262
		hideInput('addrow', !showadvopts);
1263

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

    
1272
	$('#btnadvopts').click(function(event) {
1273
		show_advopts();
1274
		checkLastRow();
1275
	});
1276

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

    
1291
});
1292
//]]>
1293
</script>
1294

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