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 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['ddnsreverse'] = isset($config['dhcpdv6'][$if]['ddnsreverse']);
138
	$pconfig['ddnsclientupdates'] = $config['dhcpdv6'][$if]['ddnsclientupdates'];
139
	list($pconfig['ntp1'], $pconfig['ntp2']) = $config['dhcpdv6'][$if]['ntpserver'];
140
	$pconfig['tftp'] = $config['dhcpdv6'][$if]['tftp'];
141
	$pconfig['ldap'] = $config['dhcpdv6'][$if]['ldap'];
142
	$pconfig['netboot'] = isset($config['dhcpdv6'][$if]['netboot']);
143
	$pconfig['bootfile_url'] = $config['dhcpdv6'][$if]['bootfile_url'];
144
	$pconfig['netmask'] = $config['dhcpdv6'][$if]['netmask'];
145
	$pconfig['numberoptions'] = $config['dhcpdv6'][$if]['numberoptions'];
146
	$pconfig['dhcpv6leaseinlocaltime'] = $config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'];
147
	if (!is_array($config['dhcpdv6'][$if]['staticmap'])) {
148
		$config['dhcpdv6'][$if]['staticmap'] = array();
149
	}
150
	$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
151
}
152

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

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

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

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

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

    
176
	foreach ($dhcrelayifs as $dhcrelayif) {
177

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

    
185
if (isset($_POST['apply'])) {
186
	$savemsg = dhcpv6_apply_changes(false);
187
} elseif (isset($_POST['save'])) {
188
	unset($input_errors);
189

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

    
194
	$pconfig = $_POST;
195

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

    
208
	/* input validation */
209
	if ($_POST['enable']) {
210
		$reqdfields = explode(" ", "range_from range_to");
211
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
212

    
213
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
214

    
215
		if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
216
			$input_errors[] = gettext("A valid prefix range must be specified.");
217
		}
218
		if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
219
			$input_errors[] = gettext("A valid prefix range must be specified.");
220
		}
221

    
222
		if ($_POST['prefixrange_from'] && $_POST['prefixrange_to'] &&
223
		    $_POST['prefixrange_length']) {
224
			$netmask = Net_IPv6::getNetmask($_POST['prefixrange_from'],
225
			    $_POST['prefixrange_length']);
226
			$netmask = Net_IPv6::compress($netmask);
227

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

    
235
			$netmask = Net_IPv6::getNetmask($_POST['prefixrange_to'],
236
			    $_POST['prefixrange_length']);
237
			$netmask = Net_IPv6::compress($netmask);
238

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

    
247
		$range_from_to_ok = true;
248

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

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

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

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

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

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

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

    
362

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

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

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

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

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

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

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

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

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

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

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

    
452
		write_config();
453

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

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

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

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

    
481
include("head.inc");
482

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

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

    
491
if ($dhcrelay_enabled) {
492
	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);
493
}
494

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

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

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

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

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

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

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

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

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

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

    
552
display_top_tabs($tab_array);
553

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

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

    
564
$form = new Form();
565

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

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

    
575
if (is_ipaddrv6($ifcfgip)) {
576

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
939

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

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

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

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

    
958
print($form);
959

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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