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
	'V4'
759
))->setHelp('Enter the primary domain name server IPv4 address for the dynamic domain name.');
760

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
940

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

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

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

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

    
959
print($form);
960

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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