Project

General

Profile

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

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

    
67
require("guiconfig.inc");
68
require_once("filter.inc");
69

    
70
if (!$g['services_dhcp_server_enable']) {
71
	header("Location: /");
72
	exit;
73
}
74

    
75
/*	Fix failover DHCP problem
76
 *	http://article.gmane.org/gmane.comp.security.firewalls.pfsense.support/18749
77
 */
78
ini_set("memory_limit", "64M");
79

    
80
$if = $_GET['if'];
81
if ($_POST['if']) {
82
	$if = $_POST['if'];
83
}
84

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

    
95
$iflist = get_configured_interface_with_descr();
96
$iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
97

    
98
/* set the starting interface */
99
if (!$if || !isset($iflist[$if])) {
100
	foreach ($iflist as $ifent => $ifname) {
101
		$oc = $config['interfaces'][$ifent];
102

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

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

    
149
$ifcfgip = get_interface_ipv6($if);
150
$ifcfgsn = get_interface_subnetv6($if);
151

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

    
157
$dhcrelay_enabled = false;
158
$dhcrelaycfg = $config['dhcrelay6'];
159

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

    
169
if ($_POST) {
170
	unset($input_errors);
171

    
172
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
173
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
174
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
175

    
176
	$pconfig = $_POST;
177

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

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

    
195
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
196

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

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

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

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

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

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

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

    
298

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

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

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

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

    
340
		unset($config['dhcpdv6'][$if]['winsserver']);
341

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

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

    
365
		unset($config['dhcpdv6'][$if]['ntpserver']);
366
		if ($_POST['ntp1']) {
367
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
368
		}
369
		if ($_POST['ntp2']) {
370
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
371
		}
372

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

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

    
384
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
385

    
386
		write_config();
387

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

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

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

    
443
	if($pconfig['numberoptions'] && is_array($pconfig['numberoptions']['item'][$idx])) {
444
	   unset($pconfig['numberoptions']['item'][$idx]);
445
	}
446
}
447

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

    
453
	array_push($pconfig['numberoptions']['item'], array('number' => null, 'value' => null));
454
}
455

    
456
$closehead = false;
457
$pgtitle = array(gettext("Services"), gettext("DHCPv6 Server"));
458
$shortcut_section = "dhcp6";
459

    
460
include("head.inc");
461

    
462
if ($input_errors)
463
	print_input_errors($input_errors);
464

    
465
if ($savemsg)
466
	print_info_box($savemsg, 'success');
467

    
468
if ($dhcrelay_enabled) {
469
	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');
470
	include("foot.inc");
471
	exit;
472
}
473

    
474
if (is_subsystem_dirty('staticmaps'))
475
	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.'));
476

    
477
/* active tabs */
478
$tab_array = array();
479
$tabscounter = 0;
480
$i = 0;
481

    
482
foreach ($iflist as $ifent => $ifname) {
483
	$oc = $config['interfaces'][$ifent];
484

    
485

    
486
	if((is_array($config['dhcpdv6'][$ifent]) && !isset($config['dhcpdv6'][$ifent]['enable']) && !(is_ipaddrv6($oc['ipaddrv6']) && (!is_linklocal($oc['ipaddrv6'])))) ||
487
		(!is_array($config['dhcpdv6'][$ifent]) && !(is_ipaddrv6($oc['ipaddrv6']) && (!is_linklocal($oc['ipaddrv6'])))))
488
		continue;
489

    
490
	if ($ifent == $if)
491
		$active = true;
492
	else
493
		$active = false;
494

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

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

    
507
			if ($ifent == $if)
508
				$active = true;
509
			else
510
				$active = false;
511

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

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

    
524
display_top_tabs($tab_array);
525

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

    
531
$form = new Form(new Form_Button(
532
	'Submit',
533
	'Save'
534
));
535

    
536
$section = new Form_Section('DHCPv6 Options');
537

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

    
545
if(is_ipaddrv6($ifcfgip)) {
546

    
547
	$section->addInput(new Form_StaticText(
548
		'Subnet',
549
		gen_subnetv6($ifcfgip, $ifcfgsn)
550
		));
551

    
552
	$section->addInput(new Form_StaticText(
553
		'Subnet Mask',
554
		$ifcfgsn . ' bits'
555
		));
556

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

    
563
if($is_olsr_enabled) {
564
	$section->addInput(new Form_Select(
565
	'netmask',
566
	'Subnet Mask',
567
	$pconfig['netmask'],
568
	array_combine(range(128, 1, -1), range(128, 1, -1))
569
	));
570
}
571

    
572
$f1 = new Form_Input(
573
	'range_from',
574
	null,
575
	'text',
576
	$pconfig['range_from']
577
);
578

    
579
$f1->setHelp('To');
580

    
581
$f2 = new Form_Input(
582
	'range_to',
583
	null,
584
	'text',
585
	$pconfig['range_to']
586
);
587

    
588
$f2->setHelp('From');
589

    
590
$group = new Form_Group('Range');
591

    
592
$group->add($f1);
593
$group->add($f2);
594

    
595
$section->add($group);
596

    
597
$f1 = new Form_Input(
598
	'prefixrange_from',
599
	null,
600
	'text',
601
	$pconfig['prefixrange_from']
602
);
603

    
604
$f1->setHelp('To');
605

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

    
613
$f2->setHelp('From');
614
$group = new Form_Group('Prefix Delegation Range');
615

    
616
$group->add($f1);
617
$group->add($f2);
618

    
619
$section->add($group);
620

    
621
$section->addInput(new Form_Select(
622
	'prefixrange_length',
623
	'Prefix Delegation Size',
624
	$pconfig['prefixrange_length'],
625
	array(
626
		'48' => '48',
627
		'52' => '52',
628
		'56' => '56',
629
		'60' => '60',
630
		'62' => '62',
631
		'63' => '63',
632
		'64' => '64'
633
		)
634
))->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.');
635

    
636
$group = new Form_Group('DNS Servers');
637

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

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

    
651
$section->addInput(new Form_Input(
652
	'domain',
653
	'Domain Name',
654
	'text',
655
	$pconfig['domain']
656
))->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. ');
657

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

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

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

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

    
690
$btndyndns = new Form_Button(
691
	'btndyndns',
692
	'Advanced'
693
);
694

    
695
$btndyndns->removeClass('btn-primary')->addClass('btn-default btn-sm');
696

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

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

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

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

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

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

    
736
$btnntp = new Form_Button(
737
	'btnntp',
738
	'Advanced'
739
);
740

    
741
$btnntp->removeClass('btn-primary')->addClass('btn-default btn-sm');
742

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

    
748
$group = new Form_Group('NTP Servers');
749

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

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

    
766
$group->addClass('ntpclass');
767

    
768
$section->add($group);
769

    
770
$btnldap = new Form_Button(
771
	'btnldap',
772
	'Advanced'
773
);
774

    
775
$btnldap->removeClass('btn-primary')->addClass('btn-default btn-sm');
776

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

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

    
789
$btnnetboot = new Form_Button(
790
	'btnnetboot',
791
	'Advanced'
792
);
793

    
794
$btnnetboot->removeClass('btn-primary')->addClass('btn-default btn-sm');
795

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

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

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

    
815
$btnadnl = new Form_Button(
816
	'btnadnl',
817
	'Advanced'
818
);
819

    
820
$btnadnl->removeClass('btn-primary')->addClass('btn-default btn-sm');
821

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

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

    
829
$title = 'Show Additional BOOTP/DHCP Options';
830

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

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

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

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

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

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

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

    
872
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm');
873

    
874
$section->addInput($btnaddopt);
875

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

    
883
print($form);
884

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

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

    
941
<nav class="action-buttons">
942
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
943
		<i class="fa fa-plus icon-embed-btn"></i>
944
		<?=gettext("Add")?>
945
	</a>
946
</nav>
947

    
948
<script type="text/javascript">
949
//<![CDATA[
950
events.push(function(){
951

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1009
	// Make the 'additional options' button a plain button, not a submit button
1010
	$("#btnadnl").prop('type','button');
1011

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

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

    
1031
<?php include('foot.inc');
(121-121/228)