Project

General

Profile

Download (36.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 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
 * Licensed under the Apache License, Version 2.0 (the "License");
15
 * you may not use this file except in compliance with the License.
16
 * You may obtain a copy of the License at
17
 *
18
 * http://www.apache.org/licenses/LICENSE-2.0
19
 *
20
 * Unless required by applicable law or agreed to in writing, software
21
 * distributed under the License is distributed on an "AS IS" BASIS,
22
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
 * See the License for the specific language governing permissions and
24
 * limitations under the License.
25
 */
26

    
27
##|+PRIV
28
##|*IDENT=page-services-dhcpv6server
29
##|*NAME=Services: DHCPv6 Server
30
##|*DESCR=Allow access to the 'Services: DHCPv6 Server' page.
31
##|*MATCH=services_dhcpv6.php*
32
##|-PRIV
33

    
34
require_once("guiconfig.inc");
35
require_once("filter.inc");
36

    
37
function dhcpv6_apply_changes($dhcpdv6_enable_changed) {
38
	$retval = 0;
39
	$retvaldhcp = 0;
40
	$retvaldns = 0;
41
	/* Stop DHCPv6 so we can cleanup leases */
42
	killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
43
	// dhcp_clean_leases();
44
	/* dnsmasq_configure calls dhcpd_configure */
45
	/* no need to restart dhcpd twice */
46
	if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic']))	{
47
		$retvaldns |= services_dnsmasq_configure();
48
		if ($retvaldns == 0) {
49
			clear_subsystem_dirty('hosts');
50
			clear_subsystem_dirty('staticmaps');
51
		}
52
	} else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) {
53
		$retvaldns |= services_unbound_configure();
54
		if ($retvaldns == 0) {
55
			clear_subsystem_dirty('unbound');
56
			clear_subsystem_dirty('staticmaps');
57
		}
58
	} else {
59
		$retvaldhcp |= services_dhcpd_configure();
60
		if ($retvaldhcp == 0) {
61
			clear_subsystem_dirty('staticmaps');
62
		}
63
	}
64
	if ($dhcpdv6_enable_changed) {
65
		$retvalfc |= filter_configure();
66
	}
67
	if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) {
68
		$retval = 1;
69
	}
70
	return $retval;
71
}
72

    
73
if (!$g['services_dhcp_server_enable']) {
74
	header("Location: /");
75
	exit;
76
}
77

    
78
$if = $_GET['if'];
79
if ($_POST['if']) {
80
	$if = $_POST['if'];
81
}
82

    
83
/* if OLSRD is enabled, allow WAN to house DHCP. */
84
if ($config['installedpackages']['olsrd']) {
85
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
86
		if ($olsrd['enable']) {
87
			$is_olsr_enabled = true;
88
			break;
89
		}
90
	}
91
}
92

    
93
$iflist = get_configured_interface_with_descr();
94
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
95

    
96
/* set the starting interface */
97
if (!$if || !isset($iflist[$if])) {
98
	foreach ($iflist as $ifent => $ifname) {
99
		$oc = $config['interfaces'][$ifent];
100
		$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
101
		    (is_ipaddrv6($oc['ipaddrv6']) &&
102
		    !is_linklocal($oc['ipaddrv6'])));
103

    
104
		if ((!is_array($config['dhcpdv6'][$ifent]) ||
105
		    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
106
		    !$valid_if_ipaddrv6) {
107
			continue;
108
		}
109
		$if = $ifent;
110
		break;
111
	}
112
}
113

    
114
if (is_array($config['dhcpdv6'][$if])) {
115
	/* DHCPv6 */
116
	if (is_array($config['dhcpdv6'][$if]['range'])) {
117
		$pconfig['range_from'] = $config['dhcpdv6'][$if]['range']['from'];
118
		$pconfig['range_to'] = $config['dhcpdv6'][$if]['range']['to'];
119
	}
120
	if (is_array($config['dhcpdv6'][$if]['prefixrange'])) {
121
		$pconfig['prefixrange_from'] = $config['dhcpdv6'][$if]['prefixrange']['from'];
122
		$pconfig['prefixrange_to'] = $config['dhcpdv6'][$if]['prefixrange']['to'];
123
		$pconfig['prefixrange_length'] = $config['dhcpdv6'][$if]['prefixrange']['prefixlength'];
124
	}
125
	$pconfig['deftime'] = $config['dhcpdv6'][$if]['defaultleasetime'];
126
	$pconfig['maxtime'] = $config['dhcpdv6'][$if]['maxleasetime'];
127
	$pconfig['domain'] = $config['dhcpdv6'][$if]['domain'];
128
	$pconfig['domainsearchlist'] = $config['dhcpdv6'][$if]['domainsearchlist'];
129
	list($pconfig['wins1'], $pconfig['wins2']) = $config['dhcpdv6'][$if]['winsserver'];
130
	list($pconfig['dns1'], $pconfig['dns2'], $pconfig['dns3'], $pconfig['dns4']) = $config['dhcpdv6'][$if]['dnsserver'];
131
	$pconfig['enable'] = isset($config['dhcpdv6'][$if]['enable']);
132
	$pconfig['ddnsdomain'] = $config['dhcpdv6'][$if]['ddnsdomain'];
133
	$pconfig['ddnsdomainprimary'] = $config['dhcpdv6'][$if]['ddnsdomainprimary'];
134
	$pconfig['ddnsdomainkeyname'] = $config['dhcpdv6'][$if]['ddnsdomainkeyname'];
135
	$pconfig['ddnsdomainkey'] = $config['dhcpdv6'][$if]['ddnsdomainkey'];
136
	$pconfig['ddnsupdate'] = isset($config['dhcpdv6'][$if]['ddnsupdate']);
137
	$pconfig['ddnsforcehostname'] = isset($config['dhcpdv6'][$if]['ddnsforcehostname']);
138
	$pconfig['ddnsreverse'] = isset($config['dhcpdv6'][$if]['ddnsreverse']);
139
	$pconfig['ddnsclientupdates'] = $config['dhcpdv6'][$if]['ddnsclientupdates'];
140
	list($pconfig['ntp1'], $pconfig['ntp2']) = $config['dhcpdv6'][$if]['ntpserver'];
141
	$pconfig['tftp'] = $config['dhcpdv6'][$if]['tftp'];
142
	$pconfig['ldap'] = $config['dhcpdv6'][$if]['ldap'];
143
	$pconfig['netboot'] = isset($config['dhcpdv6'][$if]['netboot']);
144
	$pconfig['bootfile_url'] = $config['dhcpdv6'][$if]['bootfile_url'];
145
	$pconfig['netmask'] = $config['dhcpdv6'][$if]['netmask'];
146
	$pconfig['numberoptions'] = $config['dhcpdv6'][$if]['numberoptions'];
147
	$pconfig['dhcpv6leaseinlocaltime'] = $config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'];
148
	if (!is_array($config['dhcpdv6'][$if]['staticmap'])) {
149
		$config['dhcpdv6'][$if]['staticmap'] = array();
150
	}
151
	$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
152
}
153

    
154
if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
155
	$trackifname = $config['interfaces'][$if]['track6-interface'];
156
	$trackcfg = $config['interfaces'][$trackifname];
157
	$ifcfgsn = "64";
158
	$ifcfgip = '::';
159

    
160
	$str_help_mask = dhcpv6_pd_str_help($ifcfgsn);
161
} else {
162
	$ifcfgip = get_interface_ipv6($if);
163
	$ifcfgsn = get_interface_subnetv6($if);
164
}
165

    
166
/*	 set the enabled flag which will tell us if DHCP relay is enabled
167
 *	 on any interface. We will use this to disable DHCP server since
168
 *	 the two are not compatible with each other.
169
 */
170

    
171
$dhcrelay_enabled = false;
172
$dhcrelaycfg = $config['dhcrelay6'];
173

    
174
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
175
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
176

    
177
	foreach ($dhcrelayifs as $dhcrelayif) {
178

    
179
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
180
			$dhcrelay_enabled = true;
181
			break;
182
		}
183
	}
184
}
185

    
186
if (isset($_POST['apply'])) {
187
	$changes_applied = true;
188
	$retval = dhcpv6_apply_changes(false);
189
} elseif (isset($_POST['save'])) {
190
	unset($input_errors);
191

    
192
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
193
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
194
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
195

    
196
	$pconfig = $_POST;
197

    
198
	$numberoptions = array();
199
	for ($x = 0; $x < 99; $x++) {
200
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
201
			$numbervalue = array();
202
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
203
			$numbervalue['value'] = base64_encode($_POST["value{$x}"]);
204
			$numberoptions['item'][] = $numbervalue;
205
		}
206
	}
207
	// Reload the new pconfig variable that the form uses.
208
	$pconfig['numberoptions'] = $numberoptions;
209

    
210
	/* input validation */
211

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

    
217
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
218
	}
219

    
220
	if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
221
		$input_errors[] = gettext("A valid prefix range must be specified.");
222
	}
223
	if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
224
		$input_errors[] = gettext("A valid prefix range must be specified.");
225
	}
226

    
227
	if ($_POST['prefixrange_from'] && $_POST['prefixrange_to'] &&
228
		$_POST['prefixrange_length']) {
229
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_from'],
230
			$_POST['prefixrange_length']);
231
		$netmask = Net_IPv6::compress($netmask);
232

    
233
		if ($netmask != Net_IPv6::compress(strtolower(
234
			$_POST['prefixrange_from']))) {
235
			$input_errors[] = sprintf(gettext(
236
				"Prefix Delegation From address is not a valid IPv6 Netmask for %s"),
237
				$netmask . '/' . $_POST['prefixrange_length']);
238
		}
239

    
240
		$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
241
			$_POST['prefixrange_length']);
242
		$netmask = Net_IPv6::compress($netmask);
243

    
244
		if ($netmask != Net_IPv6::compress(strtolower(
245
			$_POST['prefixrange_to']))) {
246
			$input_errors[] = sprintf(gettext(
247
				"Prefix Delegation To address is not a valid IPv6 Netmask for %s"),
248
				$netmask . '/' . $_POST['prefixrange_length']);
249
		}
250
	}
251

    
252
	$range_from_to_ok = true;
253

    
254
	if ($_POST['range_from']) {
255
		if (!is_ipaddrv6($_POST['range_from'])) {
256
			$input_errors[] = gettext("A valid range must be specified.");
257
			$range_from_to_ok = false;
258
		} elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
259
			!Net_IPv6::isInNetmask($_POST['range_from'], '::', $ifcfgsn)) {
260
			$input_errors[] = sprintf(gettext(
261
				"The prefix (upper %s bits) must be zero.  Use the form %s"),
262
				$ifcfgsn, $str_help_mask);
263
			$range_from_to_ok = false;
264
		}
265
	}
266
	if ($_POST['range_to']) {
267
		if (!is_ipaddrv6($_POST['range_to'])) {
268
			$input_errors[] = gettext("A valid range must be specified.");
269
			$range_from_to_ok = false;
270
		} elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
271
			!Net_IPv6::isInNetmask($_POST['range_to'], '::', $ifcfgsn)) {
272
			$input_errors[] = sprintf(gettext(
273
				"The prefix (upper %s bits) must be zero.  Use the form %s"),
274
				$ifcfgsn, $str_help_mask);
275
			$range_from_to_ok = false;
276
		}
277
	}
278
	if (($_POST['range_from'] && !$_POST['range_to']) || ($_POST['range_to'] && !$_POST['range_from'])) {
279
		$input_errors[] = gettext("Range From and Range To must both be entered.");
280
	}
281
	if (($_POST['gateway'] && !is_ipaddrv6($_POST['gateway']))) {
282
		$input_errors[] = gettext("A valid IPv6 address must be specified for the gateway.");
283
	}
284
	if (($_POST['dns1'] && !is_ipaddrv6($_POST['dns1'])) ||
285
		($_POST['dns2'] && !is_ipaddrv6($_POST['dns2'])) ||
286
		($_POST['dns3'] && !is_ipaddrv6($_POST['dns3'])) ||
287
		($_POST['dns4'] && !is_ipaddrv6($_POST['dns4']))) {
288
		$input_errors[] = gettext("A valid IPv6 address must be specified for each of the DNS servers.");
289
	}
290

    
291
	if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
292
		$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
293
	}
294
	if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
295
		$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
296
	}
297
	if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain']))) {
298
		$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
299
	}
300
	if (($_POST['ddnsdomain'] && !is_ipaddrv4($_POST['ddnsdomainprimary']))) {
301
		$input_errors[] = gettext("A valid primary domain name server IPv4 address must be specified for the dynamic domain name.");
302
	}
303
	if (($_POST['ddnsdomainkey'] && !$_POST['ddnsdomainkeyname']) ||
304
		($_POST['ddnsdomainkeyname'] && !$_POST['ddnsdomainkey'])) {
305
		$input_errors[] = gettext("Both a valid domain key and key name must be specified.");
306
	}
307
	if ($_POST['domainsearchlist']) {
308
		$domain_array=preg_split("/[ ;]+/", $_POST['domainsearchlist']);
309
		foreach ($domain_array as $curdomain) {
310
			if (!is_domain($curdomain)) {
311
				$input_errors[] = gettext("A valid domain search list must be specified.");
312
				break;
313
			}
314
		}
315
	}
316

    
317
	if (($_POST['ntp1'] && !is_ipaddrv6($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv6($_POST['ntp2']))) {
318
		$input_errors[] = gettext("A valid IPv6 address must be specified for the primary/secondary NTP servers.");
319
	}
320
	if (($_POST['domain'] && !is_domain($_POST['domain']))) {
321
		$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
322
	}
323
	if ($_POST['tftp'] && !is_ipaddr($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
324
		$input_errors[] = gettext("A valid IPv6 address or hostname must be specified for the TFTP server.");
325
	}
326
	if (($_POST['bootfile_url'] && !is_URL($_POST['bootfile_url']))) {
327
		$input_errors[] = gettext("A valid URL must be specified for the network bootfile.");
328
	}
329

    
330
	// Disallow a range that includes the virtualip
331
	if ($range_from_to_ok && is_array($config['virtualip']['vip'])) {
332
		foreach ($config['virtualip']['vip'] as $vip) {
333
			if ($vip['interface'] == $if) {
334
				if ($vip['subnetv6'] && is_inrange_v6($vip['subnetv6'], $_POST['range_from'], $_POST['range_to'])) {
335
					$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IPv6 address %s."), $vip['subnetv6']);
336
				}
337
			}
338
		}
339
	}
340

    
341
	$noip = false;
342
	if (is_array($a_maps)) {
343
		foreach ($a_maps as $map) {
344
			if (empty($map['ipaddrv6'])) {
345
				$noip = true;
346
			}
347
		}
348
	}
349

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

    
355
	// 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.
356
	if (!$input_errors && $_POST['range_from'] && $_POST['range_to']) {
357
		/* make sure the range lies within the current subnet */
358
		$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
359
		$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
360

    
361
		if (is_ipaddrv6($ifcfgip)) {
362
			if ((!is_inrange_v6($_POST['range_from'], $subnet_start, $subnet_end)) ||
363
				(!is_inrange_v6($_POST['range_to'], $subnet_start, $subnet_end))) {
364
				$input_errors[] = gettext("The specified range lies outside of the current subnet.");
365
			}
366
		}
367
		/* "from" cannot be higher than "to" */
368
		if (inet_pton($_POST['range_from']) > inet_pton($_POST['range_to'])) {
369
			$input_errors[] = gettext("The range is invalid (first element higher than second element).");
370
		}
371

    
372
		/* Verify static mappings do not overlap:
373
		   - available DHCP range
374
		   - prefix delegation range (FIXME: still need to be completed) */
375
		$dynsubnet_start = inet_pton($_POST['range_from']);
376
		$dynsubnet_end = inet_pton($_POST['range_to']);
377

    
378
		if (is_array($a_maps)) {
379
			foreach ($a_maps as $map) {
380
				if (empty($map['ipaddrv6'])) {
381
					continue;
382
				}
383
				if ((inet_pton($map['ipaddrv6']) > $dynsubnet_start) &&
384
					(inet_pton($map['ipaddrv6']) < $dynsubnet_end)) {
385
					$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
386
					break;
387
				}
388
			}
389
		}
390
	}
391

    
392
	if (!$input_errors) {
393
		if (!is_array($config['dhcpdv6'][$if])) {
394
			$config['dhcpdv6'][$if] = array();
395
		}
396
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
397
			$config['dhcpdv6'][$if]['range'] = array();
398
		}
399
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
400
			$config['dhcpdv6'][$if]['prefixrange'] = array();
401
		}
402

    
403
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
404
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
405
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
406
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
407
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
408
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
409
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
410
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
411

    
412
		unset($config['dhcpdv6'][$if]['winsserver']);
413

    
414
		unset($config['dhcpdv6'][$if]['dnsserver']);
415
		if ($_POST['dns1']) {
416
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
417
		}
418
		if ($_POST['dns2']) {
419
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
420
		}
421
		if ($_POST['dns3']) {
422
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
423
		}
424
		if ($_POST['dns4']) {
425
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
426
		}
427

    
428
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
429
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
430
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
431
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
432
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
433
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
434
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
435
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
436
		$config['dhcpdv6'][$if]['ddnsforcehostname'] = ($_POST['ddnsforcehostname']) ? true : false;
437
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
438
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
439

    
440
		unset($config['dhcpdv6'][$if]['ntpserver']);
441
		if ($_POST['ntp1']) {
442
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
443
		}
444
		if ($_POST['ntp2']) {
445
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
446
		}
447

    
448
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
449
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
450
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
451
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
452
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
453

    
454
		// Handle the custom options rowhelper
455
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
456
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
457
		}
458

    
459
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
460

    
461
		write_config();
462

    
463
		$changes_applied = true;
464
		$retval = dhcpv6_apply_changes($dhcpdv6_enable_changed);
465
	}
466
}
467

    
468
if ($_GET['act'] == "del") {
469
	if ($a_maps[$_GET['id']]) {
470
		unset($a_maps[$_GET['id']]);
471
		write_config();
472
		if (isset($config['dhcpdv6'][$if]['enable'])) {
473
			mark_subsystem_dirty('staticmapsv6');
474
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstaticv6'])) {
475
				mark_subsystem_dirty('hosts');
476
			}
477
		}
478
		header("Location: services_dhcpv6.php?if={$if}");
479
		exit;
480
	}
481
}
482

    
483
$pgtitle = array(gettext("Services"), htmlspecialchars(gettext("DHCPv6 Server & RA")));
484
$pglinks = array("", "services_dhcpv6.php");
485

    
486
if (!empty($if) && isset($iflist[$if])) {
487
	$pgtitle[] = $iflist[$if];
488
	$pglinks[] = "@self";
489
	$pgtitle[] = gettext("DHCPv6 Server");
490
	$pglinks[] = "@self";
491
}
492
$shortcut_section = "dhcp6";
493

    
494
include("head.inc");
495

    
496
if ($input_errors) {
497
	print_input_errors($input_errors);
498
}
499

    
500
if ($changes_applied) {
501
	print_apply_result_box($retval);
502
}
503

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

    
508
/* active tabs */
509
$tab_array = array();
510
$tabscounter = 0;
511
$i = 0;
512

    
513
foreach ($iflist as $ifent => $ifname) {
514
	$oc = $config['interfaces'][$ifent];
515
	$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
516
	    (is_ipaddrv6($oc['ipaddrv6']) &&
517
	    !is_linklocal($oc['ipaddrv6'])));
518

    
519
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
520
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
521
	    !$valid_if_ipaddrv6) {
522
		continue;
523
	}
524

    
525
	if ($ifent == $if) {
526
		$active = true;
527
	} else {
528
		$active = false;
529
	}
530

    
531
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
532
	$tabscounter++;
533
}
534

    
535
/* tack on PPPoE or PPtP servers here */
536
/* pppoe server */
537
if (is_array($config['pppoes']['pppoe'])) {
538
	foreach ($config['pppoes']['pppoe'] as $pppoe) {
539
		if ($pppoe['mode'] == "server") {
540
			$ifent = "poes". $pppoe['pppoeid'];
541
			$ifname = strtoupper($ifent);
542

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

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

    
555
if ($tabscounter == 0) {
556
	print_info_box(gettext("The DHCPv6 Server can only be enabled on interfaces configured with a static IPv6 address. This system has none."), 'danger');
557
	include("foot.inc");
558
	exit;
559
}
560

    
561
display_top_tabs($tab_array);
562

    
563
$tab_array = array();
564
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
565
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
566
display_top_tabs($tab_array, false, 'nav nav-tabs');
567

    
568
$form = new Form();
569

    
570
$section = new Form_Section('DHCPv6 Options');
571

    
572
if ($dhcrelay_enabled) {
573
	$section->addInput(new Form_Checkbox(
574
		'enable',
575
		'DHCPv6 Server',
576
		gettext("DHCPv6 Relay is currently enabled. DHCPv6 Server canot be enabled while the DHCPv6 Relay is enabled on any interface."),
577
		$pconfig['enable']
578
	))->setAttribute('disabled', true);
579
} else {
580
	$section->addInput(new Form_Checkbox(
581
		'enable',
582
		'DHCPv6 Server',
583
		'Enable DHCPv6 server on interface ' . $iflist[$if],
584
		$pconfig['enable']
585
	));
586
}
587

    
588
if (is_ipaddrv6($ifcfgip)) {
589

    
590
	if ($ifcfgip == "::") {
591
		$sntext = "Prefix Delegation";
592
	} else {
593
		$sntext = gen_subnetv6($ifcfgip, $ifcfgsn);
594
	}
595
	$section->addInput(new Form_StaticText(
596
		'Subnet',
597
		$sntext
598
		));
599

    
600
	$section->addInput(new Form_StaticText(
601
		'Subnet Mask',
602
		$ifcfgsn . ' bits'
603
		));
604

    
605
	$section->addInput(new Form_StaticText(
606
		'Available Range',
607
		$range_from = gen_subnetv6($ifcfgip, $ifcfgsn) . ' to ' . gen_subnetv6_max($ifcfgip, $ifcfgsn)
608
		))->setHelp($trackifname ? 'Prefix Delegation subnet will be appended to the beginning of the defined range':'');
609
}
610

    
611
if ($is_olsr_enabled) {
612
	$section->addInput(new Form_Select(
613
	'netmask',
614
	'Subnet Mask',
615
	$pconfig['netmask'],
616
	array_combine(range(128, 1, -1), range(128, 1, -1))
617
	));
618
}
619

    
620
$f1 = new Form_Input(
621
	'range_from',
622
	null,
623
	'text',
624
	$pconfig['range_from']
625
);
626

    
627
$f1->setHelp('From');
628

    
629
$f2 = new Form_Input(
630
	'range_to',
631
	null,
632
	'text',
633
	$pconfig['range_to']
634
);
635

    
636
$f2->setHelp('To');
637

    
638
$group = new Form_Group('Range');
639

    
640
$group->add($f1);
641
$group->add($f2);
642

    
643
$section->add($group);
644

    
645
$f1 = new Form_Input(
646
	'prefixrange_from',
647
	null,
648
	'text',
649
	$pconfig['prefixrange_from']
650
);
651

    
652
$f1->setHelp('From');
653

    
654
$f2 = new Form_Input(
655
	'prefixrange_to',
656
	null,
657
	'text',
658
	$pconfig['prefixrange_to']
659
);
660

    
661
$f2->setHelp('To');
662

    
663
$group = new Form_Group('Prefix Delegation Range');
664

    
665
$group->add($f1);
666
$group->add($f2);
667

    
668
$section->add($group);
669

    
670
$section->addInput(new Form_Select(
671
	'prefixrange_length',
672
	'Prefix Delegation Size',
673
	$pconfig['prefixrange_length'],
674
	array(
675
		'48' => '48',
676
		'52' => '52',
677
		'56' => '56',
678
		'59' => '59',
679
		'60' => '60',
680
		'61' => '61',
681
		'62' => '62',
682
		'63' => '63',
683
		'64' => '64'
684
		)
685
))->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.');
686

    
687
$group = new Form_Group('DNS Servers');
688

    
689
for ($i=1;$i<=4; $i++) {
690
	$group->add(new Form_input(
691
		'dns' . $i,
692
		null,
693
		'text',
694
		$pconfig['dns' . $i],
695
		['placeholder' => 'DNS ' . $i]
696
	));
697
}
698

    
699
$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.');
700
$section->add($group);
701

    
702
$section->addInput(new Form_Input(
703
	'domain',
704
	'Domain name',
705
	'text',
706
	$pconfig['domain']
707
))->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. ');
708

    
709
$section->addInput(new Form_Input(
710
	'domainsearchlist',
711
	'Domain search list',
712
	'text',
713
	$pconfig['domainsearchlist']
714
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
715

    
716
$section->addInput(new Form_Input(
717
	'deftime',
718
	'Default lease time',
719
	'text',
720
	$pconfig['deftime']
721
))->setHelp('Lease time in seconds. Used for clients that do not ask for a specific expiration time. ' . ' <br />' .
722
			'The default is 7200 seconds.');
723

    
724
$section->addInput(new Form_Input(
725
	'maxtime',
726
	'Max lease time',
727
	'text',
728
	$pconfig['maxtime']
729
))->setHelp('Maximum lease time for clients that ask for a specific expiration time.' . ' <br />' .
730
			'The default is 86400 seconds.');
731

    
732
$section->addInput(new Form_Checkbox(
733
	'dhcpv6leaseinlocaltime',
734
	'Time Format Change',
735
	'Change DHCPv6 display lease time from UTC to local time',
736
	$pconfig['dhcpv6leaseinlocaltime']
737
))->setHelp('By default DHCPv6 leases are displayed in UTC time. ' .
738
			'By checking this box DHCPv6 lease time will be displayed in local time and set to time zone selected. ' .
739
			'This will be used for all DHCPv6 interfaces lease time.');
740

    
741
$btnadv = new Form_Button(
742
	'btnadvdns',
743
	'Display Advanced',
744
	null,
745
	'fa-cog'
746
);
747

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

    
750
$section->addInput(new Form_StaticText(
751
	'Dynamic DNS',
752
	$btnadv
753
));
754

    
755
$section->addInput(new Form_Checkbox(
756
	'ddnsupdate',
757
	'DHCP Registration',
758
	'Enable registration of DHCP client names in DNS.',
759
	$pconfig['ddnsupdate']
760
));
761

    
762
$section->addInput(new Form_Input(
763
	'ddnsdomain',
764
	'DDNS Domain',
765
	'text',
766
	$pconfig['ddnsdomain']
767
))->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.');
768

    
769
$section->addInput(new Form_Checkbox(
770
	'ddnsforcehostname',
771
	'DDNS Hostnames',
772
	'Force dynamic DNS hostname to be the same as configured hostname for Static Mappings',
773
	$pconfig['ddnsforcehostname']
774
))->setHelp('Default registers host name option supplied by DHCP client.');
775

    
776
$section->addInput(new Form_IpAddress(
777
	'ddnsdomainprimary',
778
	'DDNS Server IP',
779
	$pconfig['ddnsdomainprimary'],
780
	'V4'
781
))->setHelp('Enter the primary domain name server IPv4 address for the dynamic domain name.');
782

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

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

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

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

    
817
$btnadv = new Form_Button(
818
	'btnadvntp',
819
	'Display Advanced',
820
	null,
821
	'fa-cog'
822
);
823

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

    
826
$section->addInput(new Form_StaticText(
827
	'NTP servers',
828
	$btnadv
829
));
830

    
831
$group = new Form_Group('NTP Servers');
832

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

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

    
849
$group->addClass('ntpclass');
850

    
851
$section->add($group);
852

    
853
$btnadv = new Form_Button(
854
	'btnadvldap',
855
	'Display Advanced',
856
	null,
857
	'fa-cog'
858
);
859

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

    
862
$section->addInput(new Form_StaticText(
863
	'LDAP',
864
	$btnadv
865
));
866

    
867
$section->addInput(new Form_Input(
868
	'ldap',
869
	'LDAP URI',
870
	'text',
871
	$pconfig['ldap']
872
));
873

    
874
$btnadv = new Form_Button(
875
	'btnadvnetboot',
876
	'Display Advanced',
877
	null,
878
	'fa-cog'
879
);
880

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

    
883
$section->addInput(new Form_StaticText(
884
	'Network booting',
885
	$btnadv
886
));
887

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

    
895
$section->addInput(new Form_Input(
896
	'bootfile_url',
897
	'Bootfile URL',
898
	'text',
899
	$pconfig['bootfile_url']
900
));
901

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

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

    
911
$section->addInput(new Form_StaticText(
912
	'Additional BOOTP/DHCP Options',
913
	$btnadv
914
));
915

    
916
$form->add($section);
917

    
918
$title = 'Show Additional BOOTP/DHCP Options';
919

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

    
927
$counter = 0;
928
$last = count($pconfig['numberoptions']['item']) - 1;
929

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

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

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

    
949
	$btn = new Form_Button(
950
		'deleterow' . $counter,
951
		'Delete',
952
		null,
953
		'fa-trash'
954
	);
955

    
956
	$btn->addClass('btn-warning');
957
	$group->add($btn);
958
	$section->add($group);
959
	$counter++;
960
}
961

    
962

    
963
$btnaddopt = new Form_Button(
964
	'addrow',
965
	'Add Option',
966
	null,
967
	'fa-plus'
968
);
969

    
970
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
971

    
972
$section->addInput($btnaddopt);
973

    
974
$section->addInput(new Form_Input(
975
	'if',
976
	null,
977
	'hidden',
978
	$if
979
));
980

    
981
print($form);
982

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

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

    
1057
<script type="text/javascript">
1058
//<![CDATA[
1059
events.push(function() {
1060

    
1061
	// Show advanced DNS options ======================================================================================
1062
	var showadvdns = false;
1063

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1250
	// On initial load
1251
	show_advdns(true);
1252
	show_advntp(true);
1253
	show_advldap(true);
1254
	show_advnetboot(true);
1255
	show_advopts(true);
1256
	if ($('#enable').prop('checked')) {
1257
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1258
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1259
	} else {
1260
		hideClass('adnloptions', true);
1261
		hideInput('addrow', true);
1262
	}
1263

    
1264
});
1265
//]]>
1266
</script>
1267

    
1268
<?php include('foot.inc');
(120-120/225)