Project

General

Profile

Download (36.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * services_dhcpv6.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Electric Sheep Fencing, LLC
7
 * Copyright (c) 2010 Seth Mos <seth.mos@dds.nl>
8
 * All rights reserved.
9
 *
10
 * originally based on m0n0wall (http://m0n0.ch/wall)
11
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
 * All rights reserved.
13
 *
14
 * 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
/*	Fix failover DHCP problem
79
 *	http://article.gmane.org/gmane.comp.security.firewalls.pfsense.support/18749
80
 */
81
ini_set("memory_limit", "64M");
82

    
83
$if = $_GET['if'];
84
if ($_POST['if']) {
85
	$if = $_POST['if'];
86
}
87

    
88
/* if OLSRD is enabled, allow WAN to house DHCP. */
89
if ($config['installedpackages']['olsrd']) {
90
	foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
91
		if ($olsrd['enable']) {
92
			$is_olsr_enabled = true;
93
			break;
94
		}
95
	}
96
}
97

    
98
$iflist = get_configured_interface_with_descr();
99
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
100

    
101
/* set the starting interface */
102
if (!$if || !isset($iflist[$if])) {
103
	foreach ($iflist as $ifent => $ifname) {
104
		$oc = $config['interfaces'][$ifent];
105
		$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
106
		    (is_ipaddrv6($oc['ipaddrv6']) &&
107
		    !is_linklocal($oc['ipaddrv6'])));
108

    
109
		if ((!is_array($config['dhcpdv6'][$ifent]) ||
110
		    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
111
		    !$valid_if_ipaddrv6) {
112
			continue;
113
		}
114
		$if = $ifent;
115
		break;
116
	}
117
}
118

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

    
158
if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
159
	$trackifname = $config['interfaces'][$if]['track6-interface'];
160
	$trackcfg = $config['interfaces'][$trackifname];
161
	$ifcfgsn = "64";
162
	$ifcfgip = '::';
163

    
164
	$str_help_mask = dhcpv6_pd_str_help($ifcfgsn);
165
} else {
166
	$ifcfgip = get_interface_ipv6($if);
167
	$ifcfgsn = get_interface_subnetv6($if);
168
}
169

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

    
175
$dhcrelay_enabled = false;
176
$dhcrelaycfg = $config['dhcrelay6'];
177

    
178
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
179
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
180

    
181
	foreach ($dhcrelayifs as $dhcrelayif) {
182

    
183
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
184
			$dhcrelay_enabled = true;
185
			break;
186
		}
187
	}
188
}
189

    
190
if (isset($_POST['apply'])) {
191
	$savemsg = dhcpv6_apply_changes(false);
192
} elseif (isset($_POST['save'])) {
193
	unset($input_errors);
194

    
195
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
196
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
197
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
198

    
199
	$pconfig = $_POST;
200

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

    
213
	/* input validation */
214
	if ($_POST['enable']) {
215
		$reqdfields = explode(" ", "range_from range_to");
216
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
217

    
218
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
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
		if ($_POST['range_from']) {
253
			if (!is_ipaddrv6($_POST['range_from'])) {
254
				$input_errors[] = gettext("A valid range must be specified.");
255
			} elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
256
			    !Net_IPv6::isInNetmask($_POST['range_from'], '::', $ifcfgsn)) {
257
				$input_errors[] = sprintf(gettext(
258
				    "The prefix (upper %s bits) must be zero.  Use the form %s"),
259
				    $ifcfgsn, $str_help_mask);
260
			}
261
		}
262
		if ($_POST['range_to']) {
263
			if (!is_ipaddrv6($_POST['range_to'])) {
264
				$input_errors[] = gettext("A valid range must be specified.");
265
			} elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
266
			    !Net_IPv6::isInNetmask($_POST['range_to'], '::', $ifcfgsn)) {
267
				$input_errors[] = sprintf(gettext(
268
				    "The prefix (upper %s bits) must be zero.  Use the form %s"),
269
				    $ifcfgsn, $str_help_mask);
270
			}
271
		}
272
		if (($_POST['gateway'] && !is_ipaddrv6($_POST['gateway']))) {
273
			$input_errors[] = gettext("A valid IPv6 address must be specified for the gateway.");
274
		}
275
		if (($_POST['dns1'] && !is_ipaddrv6($_POST['dns1'])) ||
276
		    ($_POST['dns2'] && !is_ipaddrv6($_POST['dns2'])) ||
277
		    ($_POST['dns3'] && !is_ipaddrv6($_POST['dns3'])) ||
278
		    ($_POST['dns4'] && !is_ipaddrv6($_POST['dns4']))) {
279
			$input_errors[] = gettext("A valid IPv6 address must be specified for each of the DNS servers.");
280
		}
281

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

    
308
		if (($_POST['ntp1'] && !is_ipaddrv6($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv6($_POST['ntp2']))) {
309
			$input_errors[] = gettext("A valid IPv6 address must be specified for the primary/secondary NTP servers.");
310
		}
311
		if (($_POST['domain'] && !is_domain($_POST['domain']))) {
312
			$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
313
		}
314
		if ($_POST['tftp'] && !is_ipaddr($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
315
			$input_errors[] = gettext("A valid IPv6 address or hostname must be specified for the TFTP server.");
316
		}
317
		if (($_POST['bootfile_url'] && !is_URL($_POST['bootfile_url']))) {
318
			$input_errors[] = gettext("A valid URL must be specified for the network bootfile.");
319
		}
320

    
321
		// Disallow a range that includes the virtualip
322
		if (is_array($config['virtualip']['vip'])) {
323
			foreach ($config['virtualip']['vip'] as $vip) {
324
				if ($vip['interface'] == $if) {
325
					if ($vip['subnetv6'] && is_inrange_v6($vip['subnetv6'], $_POST['range_from'], $_POST['range_to'])) {
326
						$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IPv6 address %s."), $vip['subnetv6']);
327
					}
328
				}
329
			}
330
		}
331

    
332
		$noip = false;
333
		if (is_array($a_maps)) {
334
			foreach ($a_maps as $map) {
335
				if (empty($map['ipaddrv6'])) {
336
					$noip = true;
337
				}
338
			}
339
		}
340
		if (!$input_errors) {
341
			/* make sure the range lies within the current subnet */
342
			$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
343
			$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
344

    
345
			if (is_ipaddrv6($ifcfgip)) {
346
				if ((!is_inrange_v6($_POST['range_from'], $subnet_start, $subnet_end)) ||
347
				    (!is_inrange_v6($_POST['range_to'], $subnet_start, $subnet_end))) {
348
					$input_errors[] = gettext("The specified range lies outside of the current subnet.");
349
				}
350
			}
351
			/* "from" cannot be higher than "to" */
352
			if (inet_pton($_POST['range_from']) > inet_pton($_POST['range_to'])) {
353
				$input_errors[] = gettext("The range is invalid (first element higher than second element).");
354
			}
355

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

    
361

    
362
			/* Verify static mappings do not overlap:
363
			   - available DHCP range
364
			   - prefix delegation range (FIXME: still need to be completed) */
365
			$dynsubnet_start = inet_pton($_POST['range_from']);
366
			$dynsubnet_end = inet_pton($_POST['range_to']);
367

    
368
			if (is_array($a_maps)) {
369
				foreach ($a_maps as $map) {
370
					if (empty($map['ipaddrv6'])) {
371
						continue;
372
					}
373
					if ((inet_pton($map['ipaddrv6']) > $dynsubnet_start) &&
374
					    (inet_pton($map['ipaddrv6']) < $dynsubnet_end)) {
375
						$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
376
						break;
377
					}
378
				}
379
			}
380
		}
381
	}
382

    
383
	if (!$input_errors) {
384
		if (!is_array($config['dhcpdv6'][$if])) {
385
			$config['dhcpdv6'][$if] = array();
386
		}
387
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
388
			$config['dhcpdv6'][$if]['range'] = array();
389
		}
390
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
391
			$config['dhcpdv6'][$if]['prefixrange'] = array();
392
		}
393

    
394
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
395
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
396
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
397
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
398
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
399
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
400
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
401
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
402

    
403
		unset($config['dhcpdv6'][$if]['winsserver']);
404

    
405
		unset($config['dhcpdv6'][$if]['dnsserver']);
406
		if ($_POST['dns1']) {
407
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
408
		}
409
		if ($_POST['dns2']) {
410
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
411
		}
412
		if ($_POST['dns3']) {
413
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
414
		}
415
		if ($_POST['dns4']) {
416
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
417
		}
418

    
419
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
420
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
421
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
422
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
423
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
424
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
425
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
426
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
427
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
428
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
429

    
430
		unset($config['dhcpdv6'][$if]['ntpserver']);
431
		if ($_POST['ntp1']) {
432
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
433
		}
434
		if ($_POST['ntp2']) {
435
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
436
		}
437

    
438
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
439
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
440
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
441
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
442
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
443

    
444
		// Handle the custom options rowhelper
445
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
446
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
447
		}
448

    
449
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
450

    
451
		write_config();
452

    
453
		$savemsg = dhcpv6_apply_changes($dhcpdv6_enable_changed);
454
	}
455
}
456

    
457
if ($_GET['act'] == "del") {
458
	if ($a_maps[$_GET['id']]) {
459
		unset($a_maps[$_GET['id']]);
460
		write_config();
461
		if (isset($config['dhcpdv6'][$if]['enable'])) {
462
			mark_subsystem_dirty('staticmapsv6');
463
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstaticv6'])) {
464
				mark_subsystem_dirty('hosts');
465
			}
466
		}
467
		header("Location: services_dhcpv6.php?if={$if}");
468
		exit;
469
	}
470
}
471

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

    
474
if (!empty($if) && isset($iflist[$if])) {
475
	$pgtitle[] = $iflist[$if];
476
	$pgtitle[] = gettext("DHCPv6 Server");
477
}
478
$shortcut_section = "dhcp6";
479

    
480
include("head.inc");
481

    
482
if ($input_errors) {
483
	print_input_errors($input_errors);
484
}
485

    
486
if ($savemsg) {
487
	print_info_box($savemsg, 'success');
488
}
489

    
490
if ($dhcrelay_enabled) {
491
	print_info_box(gettext("DHCPv6 Relay is currently enabled. Cannot enable the DHCPv6 Server service while the DHCPv6 Relay is enabled on any interface."), 'danger', false);
492
}
493

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

    
498
/* active tabs */
499
$tab_array = array();
500
$tabscounter = 0;
501
$i = 0;
502

    
503
foreach ($iflist as $ifent => $ifname) {
504
	$oc = $config['interfaces'][$ifent];
505
	$valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
506
	    (is_ipaddrv6($oc['ipaddrv6']) &&
507
	    !is_linklocal($oc['ipaddrv6'])));
508

    
509
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
510
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
511
	    !$valid_if_ipaddrv6) {
512
		continue;
513
	}
514

    
515
	if ($ifent == $if) {
516
		$active = true;
517
	} else {
518
		$active = false;
519
	}
520

    
521
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
522
	$tabscounter++;
523
}
524

    
525
/* tack on PPPoE or PPtP servers here */
526
/* pppoe server */
527
if (is_array($config['pppoes']['pppoe'])) {
528
	foreach ($config['pppoes']['pppoe'] as $pppoe) {
529
		if ($pppoe['mode'] == "server") {
530
			$ifent = "poes". $pppoe['pppoeid'];
531
			$ifname = strtoupper($ifent);
532

    
533
			if ($ifent == $if) {
534
				$active = true;
535
			} else {
536
				$active = false;
537
			}
538

    
539
			$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
540
			$tabscounter++;
541
		}
542
	}
543
}
544

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

    
551
display_top_tabs($tab_array);
552

    
553
$tab_array = array();
554
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
555
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
556
display_top_tabs($tab_array, false, 'nav nav-tabs');
557

    
558
if ($dhcrelay_enabled) {
559
	include("foot.inc");
560
	exit;
561
}
562

    
563
$form = new Form();
564

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

    
567
$section->addInput(new Form_Checkbox(
568
	'enable',
569
	'DHCPv6 Server',
570
	'Enable DHCPv6 server on interface ' . $iflist[$if],
571
	$pconfig['enable']
572
));
573

    
574
if (is_ipaddrv6($ifcfgip)) {
575

    
576
	if ($ifcfgip == "::") {
577
		$sntext = "Prefix Delegation";
578
	} else {
579
		$sntext = gen_subnetv6($ifcfgip, $ifcfgsn);
580
	}
581
	$section->addInput(new Form_StaticText(
582
		'Subnet',
583
		$sntext
584
		));
585

    
586
	$section->addInput(new Form_StaticText(
587
		'Subnet Mask',
588
		$ifcfgsn . ' bits'
589
		));
590

    
591
	$section->addInput(new Form_StaticText(
592
		'Available Range',
593
		$range_from = gen_subnetv6($ifcfgip, $ifcfgsn) . ' to ' . gen_subnetv6_max($ifcfgip, $ifcfgsn)
594
		))->setHelp($trackifname ? 'Prefix Delegation subnet will be appended to the beginning of the defined range':'');
595
}
596

    
597
if ($is_olsr_enabled) {
598
	$section->addInput(new Form_Select(
599
	'netmask',
600
	'Subnet Mask',
601
	$pconfig['netmask'],
602
	array_combine(range(128, 1, -1), range(128, 1, -1))
603
	));
604
}
605

    
606
$f1 = new Form_Input(
607
	'range_from',
608
	null,
609
	'text',
610
	$pconfig['range_from']
611
);
612

    
613
$f1->setHelp('From');
614

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

    
622
$f2->setHelp('To');
623

    
624
$group = new Form_Group('Range');
625

    
626
$group->add($f1);
627
$group->add($f2);
628

    
629
$section->add($group);
630

    
631
$f1 = new Form_Input(
632
	'prefixrange_from',
633
	null,
634
	'text',
635
	$pconfig['prefixrange_from']
636
);
637

    
638
$f1->setHelp('From');
639

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

    
647
$f2->setHelp('To');
648

    
649
$group = new Form_Group('Prefix Delegation Range');
650

    
651
$group->add($f1);
652
$group->add($f2);
653

    
654
$section->add($group);
655

    
656
$section->addInput(new Form_Select(
657
	'prefixrange_length',
658
	'Prefix Delegation Size',
659
	$pconfig['prefixrange_length'],
660
	array(
661
		'48' => '48',
662
		'52' => '52',
663
		'56' => '56',
664
		'60' => '60',
665
		'62' => '62',
666
		'63' => '63',
667
		'64' => '64'
668
		)
669
))->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.');
670

    
671
$group = new Form_Group('DNS Servers');
672

    
673
for ($i=1;$i<=4; $i++) {
674
	$group->add(new Form_input(
675
		'dns' . $i,
676
		null,
677
		'text',
678
		$pconfig['dns' . $i],
679
		['placeholder' => 'DNS ' . $i]
680
	));
681
}
682

    
683
$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.');
684
$section->add($group);
685

    
686
$section->addInput(new Form_Input(
687
	'domain',
688
	'Domain name',
689
	'text',
690
	$pconfig['domain']
691
))->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. ');
692

    
693
$section->addInput(new Form_Input(
694
	'domainsearchlist',
695
	'Domain search list',
696
	'text',
697
	$pconfig['domainsearchlist']
698
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator.');
699

    
700
$section->addInput(new Form_Input(
701
	'deftime',
702
	'Default lease time',
703
	'text',
704
	$pconfig['deftime']
705
))->setHelp('Lease time in seconds. Used for clients that do not ask for a specific expiration time. ' . ' <br />' .
706
			'The default is 7200 seconds.');
707

    
708
$section->addInput(new Form_Input(
709
	'maxtime',
710
	'Max lease time',
711
	'text',
712
	$pconfig['maxtime']
713
))->setHelp('Maximum lease time for clients that ask for a specific expiration time.' . ' <br />' .
714
			'The default is 86400 seconds.');
715

    
716
$section->addInput(new Form_Checkbox(
717
	'dhcpv6leaseinlocaltime',
718
	'Time Format Change',
719
	'Change DHCPv6 display lease time from UTC to local time',
720
	$pconfig['dhcpv6leaseinlocaltime']
721
))->setHelp('By default DHCPv6 leases are displayed in UTC time. ' .
722
			'By checking this box DHCPv6 lease time will be displayed in local time and set to time zone selected. ' .
723
			'This will be used for all DHCPv6 interfaces lease time.');
724

    
725
$btnadv = new Form_Button(
726
	'btnadvdns',
727
	'Display Advanced',
728
	null,
729
	'fa-cog'
730
);
731

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

    
734
$section->addInput(new Form_StaticText(
735
	'Dynamic DNS',
736
	$btnadv
737
));
738

    
739
$section->addInput(new Form_Checkbox(
740
	'ddnsupdate',
741
	'DHCP Registration',
742
	'Enable registration of DHCP client names in DNS.',
743
	$pconfig['ddnsupdate']
744
));
745

    
746
$section->addInput(new Form_Input(
747
	'ddnsdomain',
748
	'DDNS Domain',
749
	'text',
750
	$pconfig['ddnsdomain']
751
))->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.');
752

    
753
$section->addInput(new Form_IpAddress(
754
	'ddnsdomainprimary',
755
	'DDNS Server IP',
756
	$pconfig['ddnsdomainprimary']
757
))->setHelp('Enter the primary domain name server IP address for the dynamic domain name.');
758

    
759
$section->addInput(new Form_Input(
760
	'ddnsdomainkeyname',
761
	'DDNS Domain Key name',
762
	'text',
763
	$pconfig['ddnsdomainkeyname']
764
))->setHelp('Enter the dynamic DNS domain key name which will be used to register client names in the DNS server.');
765

    
766
$section->addInput(new Form_Input(
767
	'ddnsdomainkey',
768
	'DDNS Domain Key secret',
769
	'text',
770
	$pconfig['ddnsdomainkey']
771
))->setHelp('Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.');
772

    
773
$section->addInput(new Form_Select(
774
	'ddnsclientupdates',
775
	'DDNS Client Updates',
776
	$pconfig['ddnsclientupdates'],
777
	array(
778
	    'allow' => gettext('Allow'),
779
	    'deny' => gettext('Deny'),
780
	    'ignore' => gettext('Ignore'))
781
))->setHelp('How Forward entries are handled when client indicates they wish to update DNS.  ' .
782
	    'Allow prevents DHCP from updating Forward entries, Deny indicates that DHCP will ' .
783
	    'do the updates and the client should not, Ignore specifies that DHCP will do the ' .
784
	    'update and the client can also attempt the update usually using a different domain name.');
785

    
786
$section->addInput(new Form_Checkbox(
787
	'ddnsreverse',
788
	'DDNS Reverse',
789
	'Add reverse dynamic DNS entries.',
790
	$pconfig['ddnsreverse']
791
));
792

    
793
$btnadv = new Form_Button(
794
	'btnadvntp',
795
	'Display Advanced',
796
	null,
797
	'fa-cog'
798
);
799

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

    
802
$section->addInput(new Form_StaticText(
803
	'NTP servers',
804
	$btnadv
805
));
806

    
807
$group = new Form_Group('NTP Servers');
808

    
809
$group->add(new Form_Input(
810
	'ntp1',
811
	'NTP Server 1',
812
	'text',
813
	$pconfig['ntp1'],
814
	['placeholder' => 'NTP 1']
815
));
816

    
817
$group->add(new Form_Input(
818
	'ntp2',
819
	'NTP Server 2',
820
	'text',
821
	$pconfig['ntp2'],
822
	['placeholder' => 'NTP 2']
823
));
824

    
825
$group->addClass('ntpclass');
826

    
827
$section->add($group);
828

    
829
$btnadv = new Form_Button(
830
	'btnadvldap',
831
	'Display Advanced',
832
	null,
833
	'fa-cog'
834
);
835

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

    
838
$section->addInput(new Form_StaticText(
839
	'LDAP',
840
	$btnadv
841
));
842

    
843
$section->addInput(new Form_Input(
844
	'ldap',
845
	'LDAP URI',
846
	'text',
847
	$pconfig['ldap']
848
));
849

    
850
$btnadv = new Form_Button(
851
	'btnadvnetboot',
852
	'Display Advanced',
853
	null,
854
	'fa-cog'
855
);
856

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

    
859
$section->addInput(new Form_StaticText(
860
	'Network booting',
861
	$btnadv
862
));
863

    
864
$section->addInput(new Form_Checkbox(
865
	'shownetboot',
866
	'Network booting',
867
	'Enable Network Booting',
868
	$pconfig['shownetboot']
869
));
870

    
871
$section->addInput(new Form_Input(
872
	'bootfile_url',
873
	'Bootfile URL',
874
	'text',
875
	$pconfig['bootfile_url']
876
));
877

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

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

    
887
$section->addInput(new Form_StaticText(
888
	'Additional BOOTP/DHCP Options',
889
	$btnadv
890
));
891

    
892
$form->add($section);
893

    
894
$title = 'Show Additional BOOTP/DHCP Options';
895

    
896
if (!$pconfig['numberoptions']) {
897
	$noopts = true;
898
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
899
} else {
900
	$noopts = false;
901
}
902

    
903
$counter = 0;
904
$last = count($pconfig['numberoptions']['item']) - 1;
905

    
906
foreach ($pconfig['numberoptions']['item'] as $item) {
907
	$group = new Form_Group(null);
908
	$group->addClass('repeatable');
909
	$group->addClass('adnloptions');
910

    
911
	$group->add(new Form_Input(
912
		'number' . $counter,
913
		null,
914
		'text',
915
		$item['number']
916
	))->setHelp($counter == $last ? 'Number':null);
917

    
918
	$group->add(new Form_Input(
919
		'value' . $counter,
920
		null,
921
		'text',
922
		base64_decode($item['value'])
923
	))->setHelp($counter == $last ? 'Value':null);
924

    
925
	$btn = new Form_Button(
926
		'deleterow' . $counter,
927
		'Delete',
928
		null,
929
		'fa-trash'
930
	);
931

    
932
	$btn->addClass('btn-warning');
933
	$group->add($btn);
934
	$section->add($group);
935
	$counter++;
936
}
937

    
938

    
939
$btnaddopt = new Form_Button(
940
	'addrow',
941
	'Add Option',
942
	null,
943
	'fa-plus'
944
);
945

    
946
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
947

    
948
$section->addInput($btnaddopt);
949

    
950
$section->addInput(new Form_Input(
951
	'if',
952
	null,
953
	'hidden',
954
	$if
955
));
956

    
957
print($form);
958

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

    
1026
<nav class="action-buttons">
1027
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
1028
		<i class="fa fa-plus icon-embed-btn"></i>
1029
		<?=gettext("Add")?>
1030
	</a>
1031
</nav>
1032

    
1033
<script type="text/javascript">
1034
//<![CDATA[
1035
events.push(function() {
1036

    
1037
	// Show advanced DNS options ======================================================================================
1038
	var showadvdns = false;
1039

    
1040
	function show_advdns(ispageload) {
1041
		var text;
1042
		// On page load decide the initial state based on the data.
1043
		if (ispageload) {
1044
<?php
1045
			if (!$pconfig['ddnsupdate'] &&
1046
			    empty($pconfig['ddnsdomain']) &&
1047
			    empty($pconfig['ddnsdomainprimary']) &&
1048
			    empty($pconfig['ddnsdomainkeyname']) &&
1049
			    empty($pconfig['ddnsdomainkey']) &&
1050
			    (empty($pconfig['ddnsclientupdates']) || ($pconfig['ddnsclientupdates'] == "allow")) &&
1051
			    !$pconfig['ddnsreverse']) {
1052
				$showadv = false;
1053
			} else {
1054
				$showadv = true;
1055
			}
1056
?>
1057
			showadvdns = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1058
		} else {
1059
			// It was a click, swap the state.
1060
			showadvdns = !showadvdns;
1061
		}
1062

    
1063
		hideCheckbox('ddnsupdate', !showadvdns);
1064
		hideInput('ddnsdomain', !showadvdns);
1065
		hideInput('ddnsdomainprimary', !showadvdns);
1066
		hideInput('ddnsdomainkeyname', !showadvdns);
1067
		hideInput('ddnsdomainkey', !showadvdns);
1068
		hideInput('ddnsclientupdates', !showadvdns);
1069
		hideCheckbox('ddnsreverse', !showadvdns);
1070

    
1071
		if (showadvdns) {
1072
			text = "<?=gettext('Hide Advanced');?>";
1073
		} else {
1074
			text = "<?=gettext('Display Advanced');?>";
1075
		}
1076
		$('#btnadvdns').html('<i class="fa fa-cog"></i> ' + text);
1077
	}
1078

    
1079
	$('#btnadvdns').click(function(event) {
1080
		show_advdns();
1081
	});
1082

    
1083
	// Show advanced NTP options ======================================================================================
1084
	var showadvntp = false;
1085

    
1086
	function show_advntp(ispageload) {
1087
		var text;
1088
		// On page load decide the initial state based on the data.
1089
		if (ispageload) {
1090
<?php
1091
			if (empty($pconfig['ntp1']) && empty($pconfig['ntp2'])) {
1092
				$showadv = false;
1093
			} else {
1094
				$showadv = true;
1095
			}
1096
?>
1097
			showadvntp = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1098
		} else {
1099
			// It was a click, swap the state.
1100
			showadvntp = !showadvntp;
1101
		}
1102

    
1103
		hideInput('ntp1', !showadvntp);
1104
		hideInput('ntp2', !showadvntp);
1105

    
1106
		if (showadvntp) {
1107
			text = "<?=gettext('Hide Advanced');?>";
1108
		} else {
1109
			text = "<?=gettext('Display Advanced');?>";
1110
		}
1111
		$('#btnadvntp').html('<i class="fa fa-cog"></i> ' + text);
1112
	}
1113

    
1114
	$('#btnadvntp').click(function(event) {
1115
		show_advntp();
1116
	});
1117

    
1118
	// Show advanced LDAP options ======================================================================================
1119
	var showadvldap = false;
1120

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

    
1138
		hideInput('ldap', !showadvldap);
1139

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

    
1148
	$('#btnadvldap').click(function(event) {
1149
		show_advldap();
1150
	});
1151

    
1152
	// Show advanced Netboot options ======================================================================================
1153
	var showadvnetboot = false;
1154

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

    
1172
		hideCheckbox('shownetboot', !showadvnetboot);
1173
		hideInput('bootfile_url', !showadvnetboot);
1174

    
1175
		if (showadvnetboot) {
1176
			text = "<?=gettext('Hide Advanced');?>";
1177
		} else {
1178
			text = "<?=gettext('Display Advanced');?>";
1179
		}
1180
		$('#btnadvnetboot').html('<i class="fa fa-cog"></i> ' + text);
1181
	}
1182

    
1183
	$('#btnadvnetboot').click(function(event) {
1184
		show_advnetboot();
1185
	});
1186

    
1187
	// Show advanced additional opts options ===========================================================================
1188
	var showadvopts = false;
1189

    
1190
	function show_advopts(ispageload) {
1191
		var text;
1192
		// On page load decide the initial state based on the data.
1193
		if (ispageload) {
1194
<?php
1195
			if (empty($pconfig['numberoptions']) ||
1196
			    (empty($pconfig['numberoptions']['item'][0]['number']) && (empty($pconfig['numberoptions']['item'][0]['value'])))) {
1197
				$showadv = false;
1198
			} else {
1199
				$showadv = true;
1200
			}
1201
?>
1202
			showadvopts = <?php if ($showadv) {echo 'true';} else {echo 'false';} ?>;
1203
		} else {
1204
			// It was a click, swap the state.
1205
			showadvopts = !showadvopts;
1206
		}
1207

    
1208
		hideClass('adnloptions', !showadvopts);
1209
		hideInput('addrow', !showadvopts);
1210

    
1211
		if (showadvopts) {
1212
			text = "<?=gettext('Hide Advanced');?>";
1213
		} else {
1214
			text = "<?=gettext('Display Advanced');?>";
1215
		}
1216
		$('#btnadvopts').html('<i class="fa fa-cog"></i> ' + text);
1217
	}
1218

    
1219
	$('#btnadvopts').click(function(event) {
1220
		show_advopts();
1221
		checkLastRow();
1222
	});
1223

    
1224
	$('#enable').click(function() {
1225
	    do_toggle();
1226
	});
1227

    
1228
	function do_toggle() {
1229
		if ($('#enable').prop('checked')) {
1230
			$('.form-group:not(:first-child)').show();
1231
			hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1232
			hideInput('addrow', <?php echo json_encode($noopts); ?>);
1233
		} else {
1234
			$('.form-group:not(:first-child)').hide();
1235
		}
1236
	}
1237

    
1238
	// On initial load
1239
	do_toggle();
1240
	show_advdns(true);
1241
	show_advntp(true);
1242
	show_advldap(true);
1243
	show_advnetboot(true);
1244
	show_advopts(true);
1245
	if ($('#enable').prop('checked')) {
1246
		hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1247
		hideInput('addrow', <?php echo json_encode($noopts); ?>);
1248
	} else {
1249
		hideClass('adnloptions', true);
1250
		hideInput('addrow', true);
1251
	}
1252

    
1253
});
1254
//]]>
1255
</script>
1256

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