Project

General

Profile

Download (36.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * services_dhcpv6.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 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 get_std_save_message($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
	$savemsg = dhcpv6_apply_changes(false);
188
} elseif (isset($_POST['save'])) {
189
	unset($input_errors);
190

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

    
195
	$pconfig = $_POST;
196

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

    
209
	/* input validation */
210

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

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

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

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

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

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

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

    
251
	$range_from_to_ok = true;
252

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
460
		write_config();
461

    
462
		$savemsg = dhcpv6_apply_changes($dhcpdv6_enable_changed);
463
	}
464
}
465

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

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

    
483
if (!empty($if) && isset($iflist[$if])) {
484
	$pgtitle[] = $iflist[$if];
485
	$pgtitle[] = gettext("DHCPv6 Server");
486
}
487
$shortcut_section = "dhcp6";
488

    
489
include("head.inc");
490

    
491
if ($input_errors) {
492
	print_input_errors($input_errors);
493
}
494

    
495
if ($savemsg) {
496
	print_info_box($savemsg, 'success');
497
}
498

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

    
503
/* active tabs */
504
$tab_array = array();
505
$tabscounter = 0;
506
$i = 0;
507

    
508
foreach ($iflist as $ifent => $ifname) {
509
	$oc = $config['interfaces'][$ifent];
510
	$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
511
	    (is_ipaddrv6($oc['ipaddrv6']) &&
512
	    !is_linklocal($oc['ipaddrv6'])));
513

    
514
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
515
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
516
	    !$valid_if_ipaddrv6) {
517
		continue;
518
	}
519

    
520
	if ($ifent == $if) {
521
		$active = true;
522
	} else {
523
		$active = false;
524
	}
525

    
526
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
527
	$tabscounter++;
528
}
529

    
530
/* tack on PPPoE or PPtP servers here */
531
/* pppoe server */
532
if (is_array($config['pppoes']['pppoe'])) {
533
	foreach ($config['pppoes']['pppoe'] as $pppoe) {
534
		if ($pppoe['mode'] == "server") {
535
			$ifent = "poes". $pppoe['pppoeid'];
536
			$ifname = strtoupper($ifent);
537

    
538
			if ($ifent == $if) {
539
				$active = true;
540
			} else {
541
				$active = false;
542
			}
543

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

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

    
556
display_top_tabs($tab_array);
557

    
558
$tab_array = array();
559
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
560
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
561
display_top_tabs($tab_array, false, 'nav nav-tabs');
562

    
563
$form = new Form();
564

    
565
$section = new Form_Section('DHCPv6 Options');
566

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

    
583
if (is_ipaddrv6($ifcfgip)) {
584

    
585
	if ($ifcfgip == "::") {
586
		$sntext = "Prefix Delegation";
587
	} else {
588
		$sntext = gen_subnetv6($ifcfgip, $ifcfgsn);
589
	}
590
	$section->addInput(new Form_StaticText(
591
		'Subnet',
592
		$sntext
593
		));
594

    
595
	$section->addInput(new Form_StaticText(
596
		'Subnet Mask',
597
		$ifcfgsn . ' bits'
598
		));
599

    
600
	$section->addInput(new Form_StaticText(
601
		'Available Range',
602
		$range_from = gen_subnetv6($ifcfgip, $ifcfgsn) . ' to ' . gen_subnetv6_max($ifcfgip, $ifcfgsn)
603
		))->setHelp($trackifname ? 'Prefix Delegation subnet will be appended to the beginning of the defined range':'');
604
}
605

    
606
if ($is_olsr_enabled) {
607
	$section->addInput(new Form_Select(
608
	'netmask',
609
	'Subnet Mask',
610
	$pconfig['netmask'],
611
	array_combine(range(128, 1, -1), range(128, 1, -1))
612
	));
613
}
614

    
615
$f1 = new Form_Input(
616
	'range_from',
617
	null,
618
	'text',
619
	$pconfig['range_from']
620
);
621

    
622
$f1->setHelp('From');
623

    
624
$f2 = new Form_Input(
625
	'range_to',
626
	null,
627
	'text',
628
	$pconfig['range_to']
629
);
630

    
631
$f2->setHelp('To');
632

    
633
$group = new Form_Group('Range');
634

    
635
$group->add($f1);
636
$group->add($f2);
637

    
638
$section->add($group);
639

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

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

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

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

    
658
$group = new Form_Group('Prefix Delegation Range');
659

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

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

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

    
682
$group = new Form_Group('DNS Servers');
683

    
684
for ($i=1;$i<=4; $i++) {
685
	$group->add(new Form_input(
686
		'dns' . $i,
687
		null,
688
		'text',
689
		$pconfig['dns' . $i],
690
		['placeholder' => 'DNS ' . $i]
691
	));
692
}
693

    
694
$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.');
695
$section->add($group);
696

    
697
$section->addInput(new Form_Input(
698
	'domain',
699
	'Domain name',
700
	'text',
701
	$pconfig['domain']
702
))->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. ');
703

    
704
$section->addInput(new Form_Input(
705
	'domainsearchlist',
706
	'Domain search list',
707
	'text',
708
	$pconfig['domainsearchlist']
709
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
710

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

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

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

    
736
$btnadv = new Form_Button(
737
	'btnadvdns',
738
	'Display Advanced',
739
	null,
740
	'fa-cog'
741
);
742

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

    
745
$section->addInput(new Form_StaticText(
746
	'Dynamic DNS',
747
	$btnadv
748
));
749

    
750
$section->addInput(new Form_Checkbox(
751
	'ddnsupdate',
752
	'DHCP Registration',
753
	'Enable registration of DHCP client names in DNS.',
754
	$pconfig['ddnsupdate']
755
));
756

    
757
$section->addInput(new Form_Input(
758
	'ddnsdomain',
759
	'DDNS Domain',
760
	'text',
761
	$pconfig['ddnsdomain']
762
))->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.');
763

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

    
771
$section->addInput(new Form_IpAddress(
772
	'ddnsdomainprimary',
773
	'DDNS Server IP',
774
	$pconfig['ddnsdomainprimary'],
775
	'V4'
776
))->setHelp('Enter the primary domain name server IPv4 address for the dynamic domain name.');
777

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

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

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

    
805
$section->addInput(new Form_Checkbox(
806
	'ddnsreverse',
807
	'DDNS Reverse',
808
	'Add reverse dynamic DNS entries.',
809
	$pconfig['ddnsreverse']
810
));
811

    
812
$btnadv = new Form_Button(
813
	'btnadvntp',
814
	'Display Advanced',
815
	null,
816
	'fa-cog'
817
);
818

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

    
821
$section->addInput(new Form_StaticText(
822
	'NTP servers',
823
	$btnadv
824
));
825

    
826
$group = new Form_Group('NTP Servers');
827

    
828
$group->add(new Form_Input(
829
	'ntp1',
830
	'NTP Server 1',
831
	'text',
832
	$pconfig['ntp1'],
833
	['placeholder' => 'NTP 1']
834
));
835

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

    
844
$group->addClass('ntpclass');
845

    
846
$section->add($group);
847

    
848
$btnadv = new Form_Button(
849
	'btnadvldap',
850
	'Display Advanced',
851
	null,
852
	'fa-cog'
853
);
854

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

    
857
$section->addInput(new Form_StaticText(
858
	'LDAP',
859
	$btnadv
860
));
861

    
862
$section->addInput(new Form_Input(
863
	'ldap',
864
	'LDAP URI',
865
	'text',
866
	$pconfig['ldap']
867
));
868

    
869
$btnadv = new Form_Button(
870
	'btnadvnetboot',
871
	'Display Advanced',
872
	null,
873
	'fa-cog'
874
);
875

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

    
878
$section->addInput(new Form_StaticText(
879
	'Network booting',
880
	$btnadv
881
));
882

    
883
$section->addInput(new Form_Checkbox(
884
	'shownetboot',
885
	'Network booting',
886
	'Enable Network Booting',
887
	$pconfig['shownetboot']
888
));
889

    
890
$section->addInput(new Form_Input(
891
	'bootfile_url',
892
	'Bootfile URL',
893
	'text',
894
	$pconfig['bootfile_url']
895
));
896

    
897
$btnadv = new Form_Button(
898
	'btnadvopts',
899
	'Display Advanced',
900
	null,
901
	'fa-cog'
902
);
903

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

    
906
$section->addInput(new Form_StaticText(
907
	'Additional BOOTP/DHCP Options',
908
	$btnadv
909
));
910

    
911
$form->add($section);
912

    
913
$title = 'Show Additional BOOTP/DHCP Options';
914

    
915
if (!$pconfig['numberoptions']) {
916
	$noopts = true;
917
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
918
} else {
919
	$noopts = false;
920
}
921

    
922
$counter = 0;
923
$last = count($pconfig['numberoptions']['item']) - 1;
924

    
925
foreach ($pconfig['numberoptions']['item'] as $item) {
926
	$group = new Form_Group(null);
927
	$group->addClass('repeatable');
928
	$group->addClass('adnloptions');
929

    
930
	$group->add(new Form_Input(
931
		'number' . $counter,
932
		null,
933
		'text',
934
		$item['number']
935
	))->setHelp($counter == $last ? 'Number':null);
936

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

    
944
	$btn = new Form_Button(
945
		'deleterow' . $counter,
946
		'Delete',
947
		null,
948
		'fa-trash'
949
	);
950

    
951
	$btn->addClass('btn-warning');
952
	$group->add($btn);
953
	$section->add($group);
954
	$counter++;
955
}
956

    
957

    
958
$btnaddopt = new Form_Button(
959
	'addrow',
960
	'Add Option',
961
	null,
962
	'fa-plus'
963
);
964

    
965
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
966

    
967
$section->addInput($btnaddopt);
968

    
969
$section->addInput(new Form_Input(
970
	'if',
971
	null,
972
	'hidden',
973
	$if
974
));
975

    
976
print($form);
977

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

    
1045
<nav class="action-buttons">
1046
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1047
		<i class="fa fa-plus icon-embed-btn"></i>
1048
		<?=gettext("Add")?>
1049
	</a>
1050
</nav>
1051

    
1052
<script type="text/javascript">
1053
//<![CDATA[
1054
events.push(function() {
1055

    
1056
	// Show advanced DNS options ======================================================================================
1057
	var showadvdns = false;
1058

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

    
1083
		hideCheckbox('ddnsupdate', !showadvdns);
1084
		hideInput('ddnsdomain', !showadvdns);
1085
		hideCheckbox('ddnsforcehostname', !showadvdns);
1086
		hideInput('ddnsdomainprimary', !showadvdns);
1087
		hideInput('ddnsdomainkeyname', !showadvdns);
1088
		hideInput('ddnsdomainkey', !showadvdns);
1089
		hideInput('ddnsclientupdates', !showadvdns);
1090
		hideCheckbox('ddnsreverse', !showadvdns);
1091

    
1092
		if (showadvdns) {
1093
			text = "<?=gettext('Hide Advanced');?>";
1094
		} else {
1095
			text = "<?=gettext('Display Advanced');?>";
1096
		}
1097
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1098
	}
1099

    
1100
	$('#btnadvdns').click(function(event) {
1101
		show_advdns();
1102
	});
1103

    
1104
	// Show advanced NTP options ======================================================================================
1105
	var showadvntp = false;
1106

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

    
1124
		hideInput('ntp1', !showadvntp);
1125
		hideInput('ntp2', !showadvntp);
1126

    
1127
		if (showadvntp) {
1128
			text = "<?=gettext('Hide Advanced');?>";
1129
		} else {
1130
			text = "<?=gettext('Display Advanced');?>";
1131
		}
1132
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1133
	}
1134

    
1135
	$('#btnadvntp').click(function(event) {
1136
		show_advntp();
1137
	});
1138

    
1139
	// Show advanced LDAP options ======================================================================================
1140
	var showadvldap = false;
1141

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

    
1159
		hideInput('ldap', !showadvldap);
1160

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

    
1169
	$('#btnadvldap').click(function(event) {
1170
		show_advldap();
1171
	});
1172

    
1173
	// Show advanced Netboot options ======================================================================================
1174
	var showadvnetboot = false;
1175

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

    
1193
		hideCheckbox('shownetboot', !showadvnetboot);
1194
		hideInput('bootfile_url', !showadvnetboot);
1195

    
1196
		if (showadvnetboot) {
1197
			text = "<?=gettext('Hide Advanced');?>";
1198
		} else {
1199
			text = "<?=gettext('Display Advanced');?>";
1200
		}
1201
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1202
	}
1203

    
1204
	$('#btnadvnetboot').click(function(event) {
1205
		show_advnetboot();
1206
	});
1207

    
1208
	// Show advanced additional opts options ===========================================================================
1209
	var showadvopts = false;
1210

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

    
1229
		hideClass('adnloptions', !showadvopts);
1230
		hideInput('addrow', !showadvopts);
1231

    
1232
		if (showadvopts) {
1233
			text = "<?=gettext('Hide Advanced');?>";
1234
		} else {
1235
			text = "<?=gettext('Display Advanced');?>";
1236
		}
1237
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1238
	}
1239

    
1240
	$('#btnadvopts').click(function(event) {
1241
		show_advopts();
1242
		checkLastRow();
1243
	});
1244

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

    
1259
});
1260
//]]>
1261
</script>
1262

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