Project

General

Profile

Download (31.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services_dhcpv6.php
5
*/
6
/* ====================================================================
7
 *	Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved.
8
 *	Copyright (c)  2004, 2005 Scott Ullrich
9
 *	Copyright (c)  2010 Seth Mos <seth.mos@dds.nl>
10
 *
11
 *	Redistribution and use in source and binary forms, with or without modification,
12
 *	are permitted provided that the following conditions are met:
13
 *
14
 *	1. Redistributions of source code must retain the above copyright notice,
15
 *		this list of conditions and the following disclaimer.
16
 *
17
 *	2. Redistributions in binary form must reproduce the above copyright
18
 *		notice, this list of conditions and the following disclaimer in
19
 *		the documentation and/or other materials provided with the
20
 *		distribution.
21
 *
22
 *	3. All advertising materials mentioning features or use of this software
23
 *		must display the following acknowledgment:
24
 *		"This product includes software developed by the pfSense Project
25
 *		 for use in the pfSense software distribution. (http://www.pfsense.org/).
26
 *
27
 *	4. The names "pfSense" and "pfSense Project" must not be used to
28
 *		 endorse or promote products derived from this software without
29
 *		 prior written permission. For written permission, please contact
30
 *		 coreteam@pfsense.org.
31
 *
32
 *	5. Products derived from this software may not be called "pfSense"
33
 *		nor may "pfSense" appear in their names without prior written
34
 *		permission of the Electric Sheep Fencing, LLC.
35
 *
36
 *	6. Redistributions of any form whatsoever must retain the following
37
 *		acknowledgment:
38
 *
39
 *	"This product includes software developed by the pfSense Project
40
 *	for use in the pfSense software distribution (http://www.pfsense.org/).
41
 *
42
 *	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
43
 *	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44
 *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
45
 *	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
46
 *	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47
 *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48
 *	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50
 *	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
51
 *	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52
 *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
53
 *	OF THE POSSIBILITY OF SUCH DAMAGE.
54
 *
55
 *	====================================================================
56
 *
57
 */
58
/*
59
	pfSense_BUILDER_BINARIES:	/bin/rm
60
	pfSense_MODULE: interfaces
61
*/
62

    
63
##|+PRIV
64
##|*IDENT=page-services-dhcpv6server
65
##|*NAME=Services: DHCPv6 server page
66
##|*DESCR=Allow access to the 'Services: DHCPv6 server' page.
67
##|*MATCH=services_dhcpv6.php*
68
##|-PRIV
69

    
70
require("guiconfig.inc");
71
require_once("filter.inc");
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

    
106
		if ((is_array($config['dhcpdv6'][$ifent]) && !isset($config['dhcpdv6'][$ifent]['enable']) && !(is_ipaddrv6($oc['ipaddrv6']) && (!is_linklocal($oc['ipaddrv6'])))) ||
107
			(!is_array($config['dhcpdv6'][$ifent]) && !(is_ipaddrv6($oc['ipaddrv6']) && (!is_linklocal($oc['ipaddrv6']))))) {
108
			continue;
109
		}
110
		$if = $ifent;
111
		break;
112
	}
113
}
114

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

    
152
$ifcfgip = get_interface_ipv6($if);
153
$ifcfgsn = get_interface_subnetv6($if);
154

    
155
/*	 set the enabled flag which will tell us if DHCP relay is enabled
156
 *	 on any interface. We will use this to disable DHCP server since
157
 *	 the two are not compatible with each other.
158
 */
159

    
160
$dhcrelay_enabled = false;
161
$dhcrelaycfg = $config['dhcrelay6'];
162

    
163
if (is_array($dhcrelaycfg)) {
164
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
165
		if (isset($dhcrelayifconf['enable']) && isset($iflist[$dhcrelayif]) &&
166
			(!link_interface_to_bridge($dhcrelayif))) {
167
			$dhcrelay_enabled = true;
168
		}
169
	}
170
}
171

    
172
if ($_POST) {
173
	unset($input_errors);
174

    
175
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
176
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
177
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
178

    
179
	$pconfig = $_POST;
180

    
181
	$numberoptions = array();
182
	for ($x = 0; $x < 99; $x++) {
183
		if (isset($_POST["number{$x}"]) && ctype_digit($_POST["number{$x}"])) {
184
			$numbervalue = array();
185
			$numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
186
			$numbervalue['value'] = htmlspecialchars($_POST["value{$x}"]);
187
			$numberoptions['item'][] = $numbervalue;
188
		}
189
	}
190
	// Reload the new pconfig variable that the forum uses.
191
	$pconfig['numberoptions'] = $numberoptions;
192

    
193
	/* input validation */
194
	if ($_POST['enable']) {
195
		$reqdfields = explode(" ", "range_from range_to");
196
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
197

    
198
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
199

    
200
		if (($_POST['prefixrange_from'] && !is_ipaddrv6($_POST['prefixrange_from']))) {
201
			$input_errors[] = gettext("A valid range must be specified.");
202
		}
203
		if (($_POST['prefixrange_to'] && !is_ipaddrv6($_POST['prefixrange_to']))) {
204
			$input_errors[] = gettext("A valid prefix range must be specified.");
205
		}
206
		if (($_POST['range_from'] && !is_ipaddrv6($_POST['range_from']))) {
207
			$input_errors[] = gettext("A valid range must be specified.");
208
		}
209
		if (($_POST['range_to'] && !is_ipaddrv6($_POST['range_to']))) {
210
			$input_errors[] = gettext("A valid range must be specified.");
211
		}
212
		if (($_POST['gateway'] && !is_ipaddrv6($_POST['gateway']))) {
213
			$input_errors[] = gettext("A valid IPv6 address must be specified for the gateway.");
214
		}
215
		if (($_POST['dns1'] && !is_ipaddrv6($_POST['dns1'])) ||
216
			($_POST['dns2'] && !is_ipaddrv6($_POST['dns2'])) ||
217
			($_POST['dns3'] && !is_ipaddrv6($_POST['dns3'])) ||
218
			($_POST['dns4'] && !is_ipaddrv6($_POST['dns4']))) {
219
			$input_errors[] = gettext("A valid IPv6 address must be specified for each of the DNS servers.");
220
		}
221

    
222
		if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
223
			$input_errors[] = gettext("The default lease time must be at least 60 seconds.");
224
		}
225
		if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
226
			$input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time.");
227
		}
228
		if (($_POST['ddnsdomain'] && !is_domain($_POST['ddnsdomain']))) {
229
			$input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration.");
230
		}
231
		if (($_POST['ddnsdomain'] && !is_ipaddrv4($_POST['ddnsdomainprimary']))) {
232
			$input_errors[] = gettext("A valid primary domain name server IPv4 address must be specified for the dynamic domain name.");
233
		}
234
		if (($_POST['ddnsdomainkey'] && !$_POST['ddnsdomainkeyname']) ||
235
			($_POST['ddnsdomainkeyname'] && !$_POST['ddnsdomainkey'])) {
236
			$input_errors[] = gettext("You must specify both a valid domain key and key name.");
237
		}
238
		if ($_POST['domainsearchlist']) {
239
			$domain_array=preg_split("/[ ;]+/", $_POST['domainsearchlist']);
240
			foreach ($domain_array as $curdomain) {
241
				if (!is_domain($curdomain)) {
242
					$input_errors[] = gettext("A valid domain search list must be specified.");
243
					break;
244
				}
245
			}
246
		}
247

    
248
		if (($_POST['ntp1'] && !is_ipaddrv6($_POST['ntp1'])) || ($_POST['ntp2'] && !is_ipaddrv6($_POST['ntp2']))) {
249
			$input_errors[] = gettext("A valid IPv6 address must be specified for the primary/secondary NTP servers.");
250
		}
251
		if (($_POST['domain'] && !is_domain($_POST['domain']))) {
252
			$input_errors[] = gettext("A valid domain name must be specified for the DNS domain.");
253
		}
254
		if ($_POST['tftp'] && !is_ipaddr($_POST['tftp']) && !is_domain($_POST['tftp']) && !is_URL($_POST['tftp'])) {
255
			$input_errors[] = gettext("A valid IPv6 address or hostname must be specified for the TFTP server.");
256
		}
257
		if (($_POST['bootfile_url'] && !is_URL($_POST['bootfile_url']))) {
258
			$input_errors[] = gettext("A valid URL must be specified for the network bootfile.");
259
		}
260

    
261
		// Disallow a range that includes the virtualip
262
		if (is_array($config['virtualip']['vip'])) {
263
			foreach ($config['virtualip']['vip'] as $vip) {
264
				if ($vip['interface'] == $if) {
265
					if ($vip['subnetv6'] && is_inrange_v6($vip['subnetv6'], $_POST['range_from'], $_POST['range_to'])) {
266
						$input_errors[] = sprintf(gettext("The subnet range cannot overlap with virtual IPv6 address %s."), $vip['subnetv6']);
267
					}
268
				}
269
			}
270
		}
271

    
272
		$noip = false;
273
		if (is_array($a_maps)) {
274
			foreach ($a_maps as $map) {
275
				if (empty($map['ipaddrv6'])) {
276
					$noip = true;
277
				}
278
			}
279
		}
280
		if (!$input_errors) {
281
			/* make sure the range lies within the current subnet */
282
			$subnet_start = gen_subnetv6($ifcfgip, $ifcfgsn);
283
			$subnet_end = gen_subnetv6_max($ifcfgip, $ifcfgsn);
284

    
285
			if (is_ipaddrv6($ifcfgip)) {
286
				if ((!is_inrange_v6($_POST['range_from'], $subnet_start, $subnet_end)) ||
287
					(!is_inrange_v6($_POST['range_to'], $subnet_start, $subnet_end))) {
288
					$input_errors[] = gettext("The specified range lies outside of the current subnet.");
289
				}
290
			}
291
			/* "from" cannot be higher than "to" */
292
			if (inet_pton($_POST['range_from']) > inet_pton($_POST['range_to'])) {
293
				$input_errors[] = gettext("The range is invalid (first element higher than second element).");
294
			}
295

    
296
			/* make sure that the DHCP Relay isn't enabled on this interface */
297
			if (isset($config['dhcrelay'][$if]['enable'])) {
298
				$input_errors[] = sprintf(gettext("You must disable the DHCP relay on the %s interface before enabling the DHCP server."), $iflist[$if]);
299
			}
300

    
301

    
302
			/* Verify static mappings do not overlap:
303
			   - available DHCP range
304
			   - prefix delegation range (FIXME: still need to be completed) */
305
			$dynsubnet_start = inet_pton($_POST['range_from']);
306
			$dynsubnet_end = inet_pton($_POST['range_to']);
307

    
308
			if (is_array($a_maps)) {
309
				foreach ($a_maps as $map) {
310
					if (empty($map['ipaddrv6'])) {
311
						continue;
312
					}
313
					if ((inet_pton($map['ipaddrv6']) > $dynsubnet_start) &&
314
						(inet_pton($map['ipaddrv6']) < $dynsubnet_end)) {
315
						$input_errors[] = sprintf(gettext("The DHCP range cannot overlap any static DHCP mappings."));
316
						break;
317
					}
318
				}
319
			}
320
		}
321
	}
322

    
323
	if (!$input_errors) {
324
		if (!is_array($config['dhcpdv6'][$if])) {
325
			$config['dhcpdv6'][$if] = array();
326
		}
327
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
328
			$config['dhcpdv6'][$if]['range'] = array();
329
		}
330
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
331
			$config['dhcpdv6'][$if]['prefixrange'] = array();
332
		}
333

    
334
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
335
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
336
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
337
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
338
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
339
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
340
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
341
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
342

    
343
		unset($config['dhcpdv6'][$if]['winsserver']);
344

    
345
		unset($config['dhcpdv6'][$if]['dnsserver']);
346
		if ($_POST['dns1']) {
347
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
348
		}
349
		if ($_POST['dns2']) {
350
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
351
		}
352
		if ($_POST['dns3']) {
353
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
354
		}
355
		if ($_POST['dns4']) {
356
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
357
		}
358

    
359
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
360
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
361
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
362
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
363
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
364
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
365
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
366
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
367

    
368
		unset($config['dhcpdv6'][$if]['ntpserver']);
369
		if ($_POST['ntp1']) {
370
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
371
		}
372
		if ($_POST['ntp2']) {
373
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
374
		}
375

    
376
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
377
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
378
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
379
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
380
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
381

    
382
		// Handle the custom options rowhelper
383
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
384
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
385
		}
386

    
387
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
388

    
389
		write_config();
390

    
391
		$retval = 0;
392
		$retvaldhcp = 0;
393
		$retvaldns = 0;
394
		/* Stop DHCPv6 so we can cleanup leases */
395
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
396
		// dhcp_clean_leases();
397
		/* dnsmasq_configure calls dhcpd_configure */
398
		/* no need to restart dhcpd twice */
399
		if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic']))	{
400
			$retvaldns = services_dnsmasq_configure();
401
			if ($retvaldns == 0) {
402
				clear_subsystem_dirty('hosts');
403
				clear_subsystem_dirty('staticmaps');
404
			}
405
		} else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) {
406
			$retvaldns = services_unbound_configure();
407
			if ($retvaldns == 0) {
408
				clear_subsystem_dirty('unbound');
409
				clear_subsystem_dirty('staticmaps');
410
			}
411
		} else {
412
			$retvaldhcp = services_dhcpd_configure();
413
			if ($retvaldhcp == 0) {
414
				clear_subsystem_dirty('staticmaps');
415
			}
416
		}
417
		if ($dhcpdv6_enable_changed) {
418
			$retvalfc = filter_configure();
419
		}
420
		if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) {
421
			$retval = 1;
422
		}
423
		$savemsg = get_std_save_message($retval);
424
	}
425
}
426

    
427
if ($_GET['act'] == "del") {
428
	if ($a_maps[$_GET['id']]) {
429
		unset($a_maps[$_GET['id']]);
430
		write_config();
431
		if (isset($config['dhcpdv6'][$if]['enable'])) {
432
			mark_subsystem_dirty('staticmapsv6');
433
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstaticv6'])) {
434
				mark_subsystem_dirty('hosts');
435
			}
436
		}
437
		header("Location: services_dhcpv6.php?if={$if}");
438
		exit;
439
	}
440
}
441

    
442
// Delete a row in the options table
443
if($_GET['act'] == "delopt") {
444
	$idx = $_GET['id'];
445

    
446
	if($pconfig['numberoptions'] && is_array($pconfig['numberoptions']['item'][$idx])) {
447
	   unset($pconfig['numberoptions']['item'][$idx]);
448
	}
449
}
450

    
451
// Add an option row
452
if($_GET['act'] == "addopt") {
453
	if(!is_array($pconfig['numberoptions']['item']))
454
		$pconfig['numberoptions']['item'] = array();
455

    
456
	array_push($pconfig['numberoptions']['item'], array('number' => null, 'value' => null));
457
}
458

    
459
$closehead = false;
460
$pgtitle = array(gettext("Services"), gettext("DHCPv6 server"));
461
$shortcut_section = "dhcp6";
462

    
463
include("head.inc");
464

    
465
if ($input_errors)
466
	print_input_errors($input_errors);
467

    
468
if ($savemsg)
469
	print_info_box($savemsg, 'success');
470

    
471
if ($dhcrelay_enabled) {
472
	print_info_box(gettext("DHCP Relay is currently enabled. Cannot enable the DHCP Server service while the DHCP Relay is enabled on any interface."), 'danger');
473
	include("foot.inc");
474
	exit;
475
}
476

    
477
if (is_subsystem_dirty('staticmaps'))
478
	print_info_box_np(gettext('The static mapping configuration has been changed') . '.<br />' . gettext('You must apply the changes in order for them to take effect.'));
479

    
480
/* active tabs */
481
$tab_array = array();
482
$tabscounter = 0;
483
$i = 0;
484

    
485
foreach ($iflist as $ifent => $ifname) {
486
	$oc = $config['interfaces'][$ifent];
487

    
488

    
489
	if((is_array($config['dhcpdv6'][$ifent]) && !isset($config['dhcpdv6'][$ifent]['enable']) && !(is_ipaddrv6($oc['ipaddrv6']) && (!is_linklocal($oc['ipaddrv6'])))) ||
490
		(!is_array($config['dhcpdv6'][$ifent]) && !(is_ipaddrv6($oc['ipaddrv6']) && (!is_linklocal($oc['ipaddrv6'])))))
491
		continue;
492

    
493
	if ($ifent == $if)
494
		$active = true;
495
	else
496
		$active = false;
497

    
498
	$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
499
	$tabscounter++;
500
}
501

    
502
/* tack on PPPoE or PPtP servers here */
503
/* pppoe server */
504
if (is_array($config['pppoes']['pppoe'])) {
505
	foreach($config['pppoes']['pppoe'] as $pppoe) {
506
		if ($pppoe['mode'] == "server") {
507
			$ifent = "poes". $pppoe['pppoeid'];
508
			$ifname = strtoupper($ifent);
509

    
510
			if ($ifent == $if)
511
				$active = true;
512
			else
513
				$active = false;
514

    
515
			$tab_array[] = array($ifname, $active, "services_dhcpv6.php?if={$ifent}");
516
			$tabscounter++;
517
		}
518
	}
519
}
520

    
521
if ($tabscounter == 0) {
522
	print_info_box(gettext("The DHCPv6 Server can only be enabled on interfaces configured with a static IPv6 address. This system has none."), 'danger');
523
	include("foot.inc");
524
	exit;
525
}
526

    
527
$tab_array = array();
528
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
529
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
530
display_top_tabs($tab_array);
531

    
532
require_once('classes/Form.class.php');
533

    
534
$form = new Form(new Form_Button(
535
	'Submit',
536
	'Save'
537
));
538

    
539
$section = new Form_Section('DHCPv6 Options');
540

    
541
$section->addInput(new Form_Checkbox(
542
	'enable',
543
	'DHCPv6 Server',
544
	'Enable DHCPv6 server on interface ' . $iflist[$if],
545
	$pconfig['enable']
546
))->toggles('.form-group:not(:first-child)');
547

    
548
if(is_ipaddrv6($ifcfgip)) {
549

    
550
	$section->addInput(new Form_StaticText(
551
		'Subnet',
552
		gen_subnetv6($ifcfgip, $ifcfgsn)
553
		));
554

    
555
	$section->addInput(new Form_StaticText(
556
		'Subnet Mask',
557
		$ifcfgsn . ' bits'
558
		));
559

    
560
	$section->addInput(new Form_StaticText(
561
		'Available Range',
562
		$range_from = gen_subnetv6($ifcfgip, $ifcfgsn) . ' to ' . gen_subnetv6_max($ifcfgip, $ifcfgsn)
563
		));
564
}
565

    
566
if($is_olsr_enabled) {
567
	$section->addInput(new Form_Select(
568
	'netmask',
569
	'Subnetmask',
570
	$pconfig['netmask'],
571
	array_combine(range(128, 1, -1), range(128, 1, -1))
572
	));
573
}
574

    
575
$f1 = new Form_Input(
576
	'range_from',
577
	null,
578
	'text',
579
	$pconfig['range_from']
580
);
581

    
582
$f1->setHelp('To');
583

    
584
$f2 = new Form_Input(
585
	'range_to',
586
	null,
587
	'text',
588
	$pconfig['range_to']
589
);
590

    
591
$f2->setHelp('From');
592

    
593
$group = new Form_Group('Range');
594

    
595
$group->add($f1);
596
$group->add($f2);
597

    
598
$section->add($group);
599

    
600
$f1 = new Form_Input(
601
	'prefix_from',
602
	null,
603
	'text',
604
	$pconfig['prefix_from']
605
);
606

    
607
$f1->setHelp('To');
608

    
609
$f2 = new Form_Input(
610
	'prefix_to',
611
	null,
612
	'text',
613
	$pconfig['prefix_to']
614
);
615

    
616
$f2->setHelp('From');
617
$group = new Form_Group('Prefix Delegation Range');
618

    
619
$group->add($f1);
620
$group->add($f2);
621

    
622
$section->add($group);
623

    
624
$section->addInput(new Form_Select(
625
	'prefixrange_length',
626
	'Prefix Delegation Size',
627
	$pconfig['prefixrange_length'],
628
	array(
629
		'48' => '48',
630
		'52' => '52',
631
		'56' => '56',
632
		'60' => '60',
633
		'62' => '62',
634
		'63' => '63',
635
		'64' => '64'
636
		)
637
))->setHelp('You can define a Prefix range 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.');
638

    
639
$group = new Form_Group('DNS Servers');
640

    
641
for($i=1;$i<=4; $i++) {
642
	$group->add(new Form_input(
643
		'dns' . $i,
644
		null,
645
		'text',
646
		$pconfig['dns' . $i]
647
	))->setHelp('DNS ' . $i);
648
}
649

    
650
$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.');
651
$section->add($group);
652

    
653
$section->addInput(new Form_Input(
654
	'domain',
655
	'Domain Name',
656
	'text',
657
	$pconfig['domain']
658
))->setHelp('The default is to use the domain name of this system as the default domain name provided by DHCP. You may specify an alternate domain name here. ');
659

    
660
$section->addInput(new Form_Input(
661
	'domainsearchlist',
662
	'Domain search list',
663
	'text',
664
	$pconfig['domainsearchlist']
665
))->setHelp('The DHCP server can optionally provide a domain search list. Use the semicolon character as separator');
666

    
667
$section->addInput(new Form_Input(
668
	'deftime',
669
	'Default lease time',
670
	'text',
671
	$pconfig['deftime']
672
))->setHelp('Seconds . Used for clients that do not ask for a specific expiration time. ' . ' <br />' .
673
			'The default is 7200 seconds.');
674

    
675
$section->addInput(new Form_Input(
676
	'maxtime',
677
	'Max lease time',
678
	'text',
679
	$pconfig['maxtime']
680
))->setHelp('Maximum lease time for clients that ask for a specific expiration time.' . ' <br />' .
681
			'The default is 86400 seconds.');
682

    
683
$section->addInput(new Form_Checkbox(
684
	'dhcpv6leaseinlocaltime',
685
	'Time Format Change',
686
	'Change DHCPv6 display lease time from UTC to local time',
687
	$pconfig['dhcpv6leaseinlocaltime']
688
))->setHelp('By default DHCPv6 leases are displayed in UTC time. ' .
689
			'By checking this box DHCPv6 lease time will be displayed in local time and set to time zone selected. ' .
690
			'This will be used for all DHCPv6 interfaces lease time.');
691

    
692
$btndyndns = new Form_Button(
693
	'btndyndns',
694
	'Advanced'
695
);
696

    
697
$btndyndns->removeClass('btn-primary')->addClass('btn-default btn-sm');
698

    
699
$section->addInput(new Form_StaticText(
700
	'Dynamic DNS',
701
	$btndyndns . '&nbsp;' . 'Show dynamic DNS settings'
702
));
703

    
704
$section->addInput(new Form_Checkbox(
705
	'ddnsupdate',
706
	'DHCP Registration',
707
	'Enable registration of DHCP client names in DNS.',
708
	$pconfig['ddnsupdate']
709
));
710

    
711
$section->addInput(new Form_Input(
712
	'ddnsdomain',
713
	'DDNS Domain',
714
	'text',
715
	$pconfig['ddnsdomain']
716
))->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.');
717

    
718
$section->addInput(new Form_IpAddress(
719
	'ddnsdomainprimary',
720
	'DDNS Server IP',
721
	$pconfig['ddnsdomainprimary']
722
))->setHelp('Enter the primary domain name server IP address for the dynamic domain name.');
723

    
724
$section->addInput(new Form_Input(
725
	'ddnsdomainkeyname',
726
	'DDNS Domain Key name',
727
	'text',
728
	$pconfig['ddnsdomainkeyname']
729
))->setHelp('Enter the dynamic DNS domain key name which will be used to register client names in the DNS server.');
730

    
731
$section->addInput(new Form_Input(
732
	'ddnsdomainkey',
733
	'DDNS Domain Key secret',
734
	'text',
735
	$pconfig['ddnsdomainkey']
736
))->setHelp('Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.');
737

    
738
$btnntp = new Form_Button(
739
	'btnntp',
740
	'Advanced'
741
);
742

    
743
$btnntp->removeClass('btn-primary')->addClass('btn-default btn-sm');
744

    
745
$section->addInput(new Form_StaticText(
746
	'NTP servers',
747
	$btnntp . '&nbsp;' . 'Show NTP Configuration'
748
));
749

    
750
$group = new Form_Group('NTP Servers');
751

    
752
$group->add(new Form_Input(
753
	'ntp1',
754
	'NTP Server 1',
755
	'text',
756
	$pconfig['ntp1'],
757
	['placeholder' => 'NTP 1']
758
));
759

    
760
$group->add(new Form_Input(
761
	'ntp2',
762
	'NTP Server 1',
763
	'text',
764
	$pconfig['ntp2'],
765
	['placeholder' => 'NTP 2']
766
));
767

    
768
$group->addClass('ntpclass');
769

    
770
$section->add($group);
771

    
772
$btnldap = new Form_Button(
773
	'btnldap',
774
	'Advanced'
775
);
776

    
777
$btnldap->removeClass('btn-primary')->addClass('btn-default btn-sm');
778

    
779
$section->addInput(new Form_StaticText(
780
	'LDAP',
781
	$btnldap . '&nbsp;' . 'Show LDAP Configuration'
782
));
783

    
784
$section->addInput(new Form_Input(
785
	'ldap',
786
	'LDAP URI',
787
	'text',
788
	$pconfig['ldap']
789
));
790

    
791
$btnnetboot = new Form_Button(
792
	'btnnetboot',
793
	'Advanced'
794
);
795

    
796
$btnnetboot->removeClass('btn-primary')->addClass('btn-default btn-sm');
797

    
798
$section->addInput(new Form_StaticText(
799
	'Network booting',
800
	$btnnetboot . '&nbsp;' . 'Show Netwok booting'
801
));
802

    
803
$section->addInput(new Form_Checkbox(
804
	'shownetboot',
805
	'Network booting',
806
	'Enable Network Booting',
807
	$pconfig['shownetboot']
808
));
809

    
810
$section->addInput(new Form_Input(
811
	'bootfile_url',
812
	'Bootfile URL',
813
	'text',
814
	$pconfig['bootfile_url']
815
));
816

    
817
$btnadnl = new Form_Button(
818
	'btnadnl',
819
	'Advanced'
820
);
821

    
822
$btnadnl->removeClass('btn-primary')->addClass('btn-default btn-sm');
823

    
824
$section->addInput(new Form_StaticText(
825
	'Additional BOOTP/DHCP Options',
826
	$btnadnl . '&nbsp;' . 'Aditional BOOTP/DHCP Options'
827
));
828

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

    
831
$title = 'Show Additional BOOTP/DHCP Options';
832

    
833
if($pconfig['numberoptions']) {
834
	$counter = 0;
835
	$last = count($pconfig['numberoptions']['item']) - 1;
836

    
837
	foreach($pconfig['numberoptions']['item'] as $item) {
838
		$group = new Form_Group(null);
839

    
840
		$group->add(new Form_Input(
841
			'number' . $counter,
842
			null,
843
			'text',
844
			$item['number']
845
		))->setHelp($counter == $last ? 'Number':null);
846

    
847
		$group->add(new Form_Input(
848
			'value' . $counter,
849
			null,
850
			'text',
851
			$item['value']
852
		))->setHelp($counter == $last ? 'Value':null);
853

    
854
		$btn = new Form_Button(
855
			'btn' . $counter,
856
			'Delete',
857
			'services_dhcpv6.php?if=' . $if . '&act=delopt' . '&id=' . $counter
858
		);
859

    
860
		$btn->removeClass('btn-primary')->addClass('btn-danger btn-xs adnlopt');
861
		$group->addClass('adnlopt');
862
		$group->add($btn);
863
		$section->add($group);
864
		$counter++;
865
	}
866
}
867

    
868
$btnaddopt = new Form_Button(
869
	'btnaddopt',
870
	'Add Option',
871
	'services_dhcpv6.php?if=' . $if . '&act=addopt'
872
);
873

    
874
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
875

    
876
$section->addInput($btnaddopt);
877

    
878
$section->addInput(new Form_Input(
879
	'if',
880
	null,
881
	'hidden',
882
	$if
883
));
884

    
885
print($form);
886

    
887
print_info_box(gettext('The DNS servers entered in ') . '<a href="system.php">' . gettext(' System: General setup') . '</a>' .
888
			   gettext(' (or the ') . '<a href="services_dnsmasq.php"/>' . gettext('DNS forwarder') . '</a>, ' . gettext('if enabled) ') .
889
			   gettext('will be assigned to clients by the DHCP server.') . '<br />' .
890
			   gettext('The DHCP lease table can be viewed on the ') . '<a href="status_dhcpv6_leases.php">' .
891
			   gettext('Status: DHCPv6 leases') . '</a>' . gettext(' page.'));
892
?>
893

    
894
<div class="panel panel-default">
895
	<div class="panel-heading"><h2 class="panel-title">DHCPv6 Static Mappings for this interface.</h2></div>
896
	<div class="panel-body table-responsive">
897
		<table class="table table-striped table-hover table-condensed">
898
			<thead>
899
				<tr>
900
					<th><?=gettext("DUID")?></th>
901
					<th><?=gettext("IPv6 address")?></th>
902
					<th><?=gettext("Hostname")?></th>
903
					<th><?=gettext("Description")?></th>
904
					<th><!-- Buttons --></th>
905
				</tr>
906
			</thead>
907
			<tbody>
908
<?php
909
if(is_array($a_maps)):
910
	$i = 0;
911
	foreach ($a_maps as $mapent):
912
		if($mapent['duid'] != "" or $mapent['ipaddrv6'] != ""):
913
?>
914
				<tr>
915
					<td>
916
						<?=htmlspecialchars($mapent['duid'])?>
917
					</td>
918
					<td>
919
						<?=htmlspecialchars($mapent['ipaddrv6'])?>
920
					</td>
921
					<td>
922
						<?=htmlspecialchars($mapent['hostname'])?>
923
					</td>
924
					<td>
925
						<?=htmlspecialchars($mapent['descr'])?>
926
					</td>
927
					<td>
928
						<a href="services_dhcpv6_edit.php?if=<?=$if?>&amp;id=<?=$i?>" class="btn btn-info btn-xs"/>Edit</a>
929
						<a href="services_dhcpv6.php?if=<?=$if?>&amp;act=del&amp;id=<?=$i?>" class="btn btn-danger btn-xs"/>Delete</a>
930
					</td>
931
				</tr>
932
<?php
933
		endif;
934
	$i++;
935
	endforeach;
936
endif;
937
?>
938
			</tbody>
939
		</table>
940
	</div>
941
</div>
942

    
943
<nav class="action-buttons">
944
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>Add</a>
945
</nav>
946

    
947
<script>
948
//<![CDATA[
949
events.push(function(){
950

    
951
	function hideDDNS(hide) {
952
		hideCheckBox('ddnsupdate', hide);
953
		hideInput('ddnsdomain', hide);
954
		hideInput('ddnsdomainprimary', hide);
955
		hideInput('ddnsdomainkeyname', hide);
956
		hideInput('ddnsdomainkey', hide);
957
	}
958

    
959
	// Make the ‘Copy My MAC’ button a plain button, not a submit button
960
	$("#btnmymac").prop('type','button');
961

    
962
	// On click, copy the hidden 'mymac' text to the 'mac' input
963
	$("#btnmymac").click(function() {
964
		$('#mac').val('<?=$mymac?>');
965
	});
966

    
967
	// Make the ‘tftp’ button a plain button, not a submit button
968
	$("#btntftp").prop('type','button');
969

    
970
	// Show tftp controls
971
	$("#btntftp").click(function() {
972
		hideInput('tftp', false);
973
	});
974

    
975
	// Make the ‘ntp’ button a plain button, not a submit button
976
	$("#btnntp").prop('type','button');
977

    
978
	// Show ntp controls
979
	$("#btnntp").click(function() {
980
		hideClass('ntpclass', false);
981
	});
982

    
983
	// Make the ‘ddns’ button a plain button, not a submit button
984
	$("#btndyndns").prop('type','button');
985

    
986
	// Show ddns controls
987
	$("#btndyndns").click(function() {
988
		hideDDNS(false);
989
	});
990

    
991
	// Make the ‘ldap’ button a plain button, not a submit button
992
	$("#btnldap").prop('type','button');
993

    
994
	// Show ldap controls
995
	$("#btnldap").click(function() {
996
		hideInput('ldap', false);
997
	});
998

    
999
	// Make the ‘netboot’ button a plain button, not a submit button
1000
	$("#btnnetboot").prop('type','button');
1001

    
1002
	// Show netboot controls
1003
	$("#btnnetboot").click(function() {
1004
		hideInput('bootfile_url', false);
1005
		hideCheckBox('shownetboot', false);
1006
	});
1007

    
1008
	// Make the ‘aditional options’ button a plain button, not a submit button
1009
	$("#btnadnl").prop('type','button');
1010

    
1011
	// Show aditional  controls
1012
	$("#btnadnl").click(function() {
1013
		hideClass('adnlopt', false);
1014
		hideInput('btnaddopt', false);
1015
	});
1016

    
1017
	// On initial load
1018
	hideDDNS(true);
1019
	hideClass('ntpclass', true);
1020
	hideInput('tftp', true);
1021
	hideInput('ldap', true);
1022
	hideInput('bootfile_url', true);
1023
	hideCheckBox('shownetboot', true);
1024
	hideClass('adnlopt', true);
1025
	hideInput('btnaddopt', true);
1026
});
1027
//]]>
1028
</script>
1029

    
1030
<?php include('foot.inc');
(135-135/234)