Project

General

Profile

Download (32.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
		$valid_if_ipaddrv6 = (bool) (is_ipaddrv6($oc['ipaddrv6']) &&
103
		    !is_linklocal($oc['ipaddrv6']));
104

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

    
154
$ifcfgip = get_interface_ipv6($if);
155
$ifcfgsn = get_interface_subnetv6($if);
156

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

    
162
$dhcrelay_enabled = false;
163
$dhcrelaycfg = $config['dhcrelay6'];
164

    
165
if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycfg['interface']) && !empty($dhcrelaycfg['interface'])) {
166
	$dhcrelayifs = explode(",", $dhcrelaycfg['interface']);
167

    
168
	foreach ($dhcrelayifs as $dhcrelayif) {
169

    
170
		if (isset($iflist[$dhcrelayif]) && (!link_interface_to_bridge($dhcrelayif))) {
171
			$dhcrelay_enabled = true;
172
			break;
173
		}
174
	}
175
}
176

    
177
if ($_POST) {
178
	unset($input_errors);
179

    
180
	$old_dhcpdv6_enable = ($pconfig['enable'] == true);
181
	$new_dhcpdv6_enable = ($_POST['enable'] ? true : false);
182
	$dhcpdv6_enable_changed = ($old_dhcpdv6_enable != $new_dhcpdv6_enable);
183

    
184
	$pconfig = $_POST;
185

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

    
198
	/* input validation */
199
	if ($_POST['enable']) {
200
		$reqdfields = explode(" ", "range_from range_to");
201
		$reqdfieldsn = array(gettext("Range begin"), gettext("Range end"));
202

    
203
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
204

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

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

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

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

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

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

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

    
306

    
307
			/* Verify static mappings do not overlap:
308
			   - available DHCP range
309
			   - prefix delegation range (FIXME: still need to be completed) */
310
			$dynsubnet_start = inet_pton($_POST['range_from']);
311
			$dynsubnet_end = inet_pton($_POST['range_to']);
312

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

    
328
	if (!$input_errors) {
329
		if (!is_array($config['dhcpdv6'][$if])) {
330
			$config['dhcpdv6'][$if] = array();
331
		}
332
		if (!is_array($config['dhcpdv6'][$if]['range'])) {
333
			$config['dhcpdv6'][$if]['range'] = array();
334
		}
335
		if (!is_array($config['dhcpdv6'][$if]['prefixrange'])) {
336
			$config['dhcpdv6'][$if]['prefixrange'] = array();
337
		}
338

    
339
		$config['dhcpdv6'][$if]['range']['from'] = $_POST['range_from'];
340
		$config['dhcpdv6'][$if]['range']['to'] = $_POST['range_to'];
341
		$config['dhcpdv6'][$if]['prefixrange']['from'] = $_POST['prefixrange_from'];
342
		$config['dhcpdv6'][$if]['prefixrange']['to'] = $_POST['prefixrange_to'];
343
		$config['dhcpdv6'][$if]['prefixrange']['prefixlength'] = $_POST['prefixrange_length'];
344
		$config['dhcpdv6'][$if]['defaultleasetime'] = $_POST['deftime'];
345
		$config['dhcpdv6'][$if]['maxleasetime'] = $_POST['maxtime'];
346
		$config['dhcpdv6'][$if]['netmask'] = $_POST['netmask'];
347

    
348
		unset($config['dhcpdv6'][$if]['winsserver']);
349

    
350
		unset($config['dhcpdv6'][$if]['dnsserver']);
351
		if ($_POST['dns1']) {
352
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns1'];
353
		}
354
		if ($_POST['dns2']) {
355
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns2'];
356
		}
357
		if ($_POST['dns3']) {
358
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns3'];
359
		}
360
		if ($_POST['dns4']) {
361
			$config['dhcpdv6'][$if]['dnsserver'][] = $_POST['dns4'];
362
		}
363

    
364
		$config['dhcpdv6'][$if]['domain'] = $_POST['domain'];
365
		$config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist'];
366
		$config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false;
367
		$config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain'];
368
		$config['dhcpdv6'][$if]['ddnsdomainprimary'] = $_POST['ddnsdomainprimary'];
369
		$config['dhcpdv6'][$if]['ddnsdomainkeyname'] = $_POST['ddnsdomainkeyname'];
370
		$config['dhcpdv6'][$if]['ddnsdomainkey'] = $_POST['ddnsdomainkey'];
371
		$config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false;
372
		$config['dhcpdv6'][$if]['ddnsreverse'] = ($_POST['ddnsreverse']) ? true : false;
373
		$config['dhcpdv6'][$if]['ddnsclientupdates'] = $_POST['ddnsclientupdates'];
374

    
375
		unset($config['dhcpdv6'][$if]['ntpserver']);
376
		if ($_POST['ntp1']) {
377
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp1'];
378
		}
379
		if ($_POST['ntp2']) {
380
			$config['dhcpdv6'][$if]['ntpserver'][] = $_POST['ntp2'];
381
		}
382

    
383
		$config['dhcpdv6'][$if]['tftp'] = $_POST['tftp'];
384
		$config['dhcpdv6'][$if]['ldap'] = $_POST['ldap'];
385
		$config['dhcpdv6'][$if]['netboot'] = ($_POST['netboot']) ? true : false;
386
		$config['dhcpdv6'][$if]['bootfile_url'] = $_POST['bootfile_url'];
387
		$config['dhcpdv6'][$if]['dhcpv6leaseinlocaltime'] = $_POST['dhcpv6leaseinlocaltime'];
388

    
389
		// Handle the custom options rowhelper
390
		if (isset($config['dhcpdv6'][$if]['numberoptions']['item'])) {
391
			unset($config['dhcpdv6'][$if]['numberoptions']['item']);
392
		}
393

    
394
		$config['dhcpdv6'][$if]['numberoptions'] = $numberoptions;
395

    
396
		write_config();
397

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

    
434
if ($_GET['act'] == "del") {
435
	if ($a_maps[$_GET['id']]) {
436
		unset($a_maps[$_GET['id']]);
437
		write_config();
438
		if (isset($config['dhcpdv6'][$if]['enable'])) {
439
			mark_subsystem_dirty('staticmapsv6');
440
			if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstaticv6'])) {
441
				mark_subsystem_dirty('hosts');
442
			}
443
		}
444
		header("Location: services_dhcpv6.php?if={$if}");
445
		exit;
446
	}
447
}
448

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

    
451
if (!empty($if) && !$dhcrelay_enabled && isset($iflist[$if])) {
452
	$pgtitle[] = $iflist[$if];
453
	$pgtitle[] = gettext("DHCPv6 Server");
454
}
455
$shortcut_section = "dhcp6";
456

    
457
include("head.inc");
458

    
459
if ($input_errors) {
460
	print_input_errors($input_errors);
461
}
462

    
463
if ($savemsg) {
464
	print_info_box($savemsg, 'success');
465
}
466

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

    
473
if (is_subsystem_dirty('staticmaps')) {
474
	print_apply_box(gettext('The static mapping configuration has been changed.') . '<br />' . gettext('You must apply the changes in order for them to take effect.'));
475
}
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
	$valid_if_ipaddrv6 = (bool) (is_ipaddrv6($oc['ipaddrv6']) &&
485
	    !is_linklocal($oc['ipaddrv6']));
486

    
487
	if ((!is_array($config['dhcpdv6'][$ifent]) ||
488
	    !isset($config['dhcpdv6'][$ifent]['enable'])) &&
489
	    !$valid_if_ipaddrv6) {
490
		continue;
491
	}
492

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

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

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

    
511
			if ($ifent == $if) {
512
				$active = true;
513
			} else {
514
				$active = false;
515
			}
516

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

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

    
529
display_top_tabs($tab_array);
530

    
531
$tab_array = array();
532
$tab_array[] = array(gettext("DHCPv6 Server"),		 true,	"services_dhcpv6.php?if={$if}");
533
$tab_array[] = array(gettext("Router Advertisements"), false, "services_router_advertisements.php?if={$if}");
534
display_top_tabs($tab_array, false, 'nav nav-tabs');
535

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

    
541
$section = new Form_Section('DHCPv6 Options');
542

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

    
550
if (is_ipaddrv6($ifcfgip)) {
551

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

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

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

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

    
577
$f1 = new Form_Input(
578
	'range_from',
579
	null,
580
	'text',
581
	$pconfig['range_from']
582
)->setHelp('From');
583

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

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

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

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

    
598
$f1 = new Form_Input(
599
	'prefixrange_from',
600
	null,
601
	'text',
602
	$pconfig['prefixrange_from']
603
)->setHelp('From');
604

    
605
$f2 = new Form_Input(
606
	'prefixrange_to',
607
	null,
608
	'text',
609
	$pconfig['prefixrange_to']
610
)->setHelp('To');
611

    
612
$group = new Form_Group('Prefix Delegation Range');
613

    
614
$group->add($f1);
615
$group->add($f2);
616

    
617
$section->add($group);
618

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

    
634
$group = new Form_Group('DNS Servers');
635

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

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

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

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

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

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

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

    
688
$btndyndns = new Form_Button(
689
	'btndyndns',
690
	'Advanced'
691
);
692

    
693
$btndyndns->removeClass('btn-primary')->addClass('btn-default btn-sm');
694

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

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

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

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

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

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

    
734
$section->addInput(new Form_Select(
735
	'ddnsclientupdates',
736
	'DDNS Client Updates',
737
	$pconfig['ddnsclientupdates'],
738
	array(
739
	    'allow' => gettext('Allow'),
740
	    'deny' => gettext('Deny'),
741
	    'ignore' => gettext('Ignore'))
742
))->setHelp('How Forward entries are handled when client indicates they wish to update DNS.  ' .
743
	    'Allow prevents DHCP from updating Forward entries, Deny indicates that DHCP will ' .
744
	    'do the updates and the client should not, Ignore specifies that DHCP will do the ' .
745
	    'update and the client can also attempt the update usually using a different domain name.');
746

    
747
$section->addInput(new Form_Checkbox(
748
	'ddnsreverse',
749
	'DDNS Reverse',
750
	'Add reverse dynamic DNS entries.',
751
	$pconfig['ddnsreverse']
752
));
753

    
754
$btnntp = new Form_Button(
755
	'btnntp',
756
	'Advanced'
757
);
758

    
759
$btnntp->removeClass('btn-primary')->addClass('btn-default btn-sm');
760

    
761
$section->addInput(new Form_StaticText(
762
	'NTP servers',
763
	$btnntp . '&nbsp;' . 'Show NTP Configuration'
764
));
765

    
766
$group = new Form_Group('NTP Servers');
767

    
768
$group->add(new Form_Input(
769
	'ntp1',
770
	'NTP Server 1',
771
	'text',
772
	$pconfig['ntp1'],
773
	['placeholder' => 'NTP 1']
774
));
775

    
776
$group->add(new Form_Input(
777
	'ntp2',
778
	'NTP Server 2',
779
	'text',
780
	$pconfig['ntp2'],
781
	['placeholder' => 'NTP 2']
782
));
783

    
784
$group->addClass('ntpclass');
785

    
786
$section->add($group);
787

    
788
$btnldap = new Form_Button(
789
	'btnldap',
790
	'Advanced'
791
);
792

    
793
$btnldap->removeClass('btn-primary')->addClass('btn-default btn-sm');
794

    
795
$section->addInput(new Form_StaticText(
796
	'LDAP',
797
	$btnldap . '&nbsp;' . 'Show LDAP Configuration'
798
));
799

    
800
$section->addInput(new Form_Input(
801
	'ldap',
802
	'LDAP URI',
803
	'text',
804
	$pconfig['ldap']
805
));
806

    
807
$btnnetboot = new Form_Button(
808
	'btnnetboot',
809
	'Advanced'
810
);
811

    
812
$btnnetboot->removeClass('btn-primary')->addClass('btn-default btn-sm');
813

    
814
$section->addInput(new Form_StaticText(
815
	'Network booting',
816
	$btnnetboot . '&nbsp;' . 'Show Network booting'
817
));
818

    
819
$section->addInput(new Form_Checkbox(
820
	'shownetboot',
821
	'Network booting',
822
	'Enable Network Booting',
823
	$pconfig['shownetboot']
824
));
825

    
826
$section->addInput(new Form_Input(
827
	'bootfile_url',
828
	'Bootfile URL',
829
	'text',
830
	$pconfig['bootfile_url']
831
));
832

    
833
$btnadnl = new Form_Button(
834
	'btnadnl',
835
	'Advanced'
836
);
837

    
838
$btnadnl->removeClass('btn-primary')->addClass('btn-default btn-sm');
839

    
840
$section->addInput(new Form_StaticText(
841
	'Additional BOOTP/DHCP Options',
842
	$btnadnl . '&nbsp;' . 'Additional BOOTP/DHCP Options'
843
));
844

    
845
$form->add($section);
846

    
847
$title = 'Show Additional BOOTP/DHCP Options';
848

    
849
if (!$pconfig['numberoptions']) {
850
	$noopts = true;
851
	$pconfig['numberoptions']['item'] = array(0 => array('number' => "", 'value' => ""));
852
} else {
853
	$noopts = false;
854
}
855

    
856
$counter = 0;
857
$last = count($pconfig['numberoptions']['item']) - 1;
858

    
859
foreach ($pconfig['numberoptions']['item'] as $item) {
860
	$group = new Form_Group(null);
861
	$group->addClass('repeatable');
862
	$group->addClass('adnloptions');
863

    
864
	$group->add(new Form_Input(
865
		'number' . $counter,
866
		null,
867
		'text',
868
		$item['number']
869
	))->setHelp($counter == $last ? 'Number':null);
870

    
871
	$group->add(new Form_Input(
872
		'value' . $counter,
873
		null,
874
		'text',
875
		base64_decode($item['value'])
876
	))->setHelp($counter == $last ? 'Value':null);
877

    
878
	$btn = new Form_Button(
879
		'deleterow' . $counter,
880
		'Delete'
881
	);
882

    
883
	$btn->removeClass('btn-primary')->addClass('btn-warning');
884
	$group->add($btn);
885
	$section->add($group);
886
	$counter++;
887
}
888

    
889

    
890
$btnaddopt = new Form_Button(
891
	'addrowt',
892
	'Add Option'
893
);
894

    
895
$btnaddopt->removeClass('btn-primary')->addClass('btn-success btn-sm')->addClass('adnloptions');
896

    
897
$section->addInput($btnaddopt);
898

    
899
$section->addInput(new Form_Input(
900
	'if',
901
	null,
902
	'hidden',
903
	$if
904
));
905

    
906
print($form);
907

    
908
?>
909
<div class="infoblock blockopen">
910
<?php
911
print_info_box(
912
	sprintf(
913
		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.'),
914
		'<a href="system.php">',
915
		'<a href="services_dnsmasq.php"/>',
916
		'</a>') . 
917
	'<br />' .
918
	sprintf(
919
		gettext('The DHCP lease table can be viewed on the %1$sStatus: DHCPv6 leases%2$s page.'),
920
		'<a href="status_dhcpv6_leases.php">',
921
		'</a>'),
922
	'info',
923
	false);
924
?>
925
</div>
926
<div class="panel panel-default">
927
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("DHCPv6 Static Mappings for this Interface");?></h2></div>
928
	<div class="panel-body table-responsive">
929
		<table class="table table-striped table-hover table-condensed">
930
			<thead>
931
				<tr>
932
					<th><?=gettext("DUID")?></th>
933
					<th><?=gettext("IPv6 address")?></th>
934
					<th><?=gettext("Hostname")?></th>
935
					<th><?=gettext("Description")?></th>
936
					<th><!-- Buttons --></th>
937
				</tr>
938
			</thead>
939
			<tbody>
940
<?php
941
if (is_array($a_maps)):
942
	$i = 0;
943
	foreach ($a_maps as $mapent):
944
		if ($mapent['duid'] != "" or $mapent['ipaddrv6'] != ""):
945
?>
946
				<tr>
947
					<td>
948
						<?=htmlspecialchars($mapent['duid'])?>
949
					</td>
950
					<td>
951
						<?=htmlspecialchars($mapent['ipaddrv6'])?>
952
					</td>
953
					<td>
954
						<?=htmlspecialchars($mapent['hostname'])?>
955
					</td>
956
					<td>
957
						<?=htmlspecialchars($mapent['descr'])?>
958
					</td>
959
					<td>
960
						<a class="fa fa-pencil"	title="<?=gettext('Edit static mapping')?>" href="services_dhcpv6_edit.php?if=<?=$if?>&amp;id=<?=$i?>"></a>
961
						<a class="fa fa-trash"	title="<?=gettext('Delete static mapping')?>" href="services_dhcpv6.php?if=<?=$if?>&amp;act=del&amp;id=<?=$i?>"></a>
962
					</td>
963
				</tr>
964
<?php
965
		endif;
966
	$i++;
967
	endforeach;
968
endif;
969
?>
970
			</tbody>
971
		</table>
972
	</div>
973
</div>
974

    
975
<nav class="action-buttons">
976
	<a href="services_dhcpv6_edit.php?if=<?=$if?>" class="btn btn-sm btn-success"/>
977
		<i class="fa fa-plus icon-embed-btn"></i>
978
		<?=gettext("Add")?>
979
	</a>
980
</nav>
981

    
982
<script type="text/javascript">
983
//<![CDATA[
984
events.push(function() {
985

    
986
	function hideDDNS(hide) {
987
		hideCheckbox('ddnsupdate', hide);
988
		hideInput('ddnsdomain', hide);
989
		hideInput('ddnsdomainprimary', hide);
990
		hideInput('ddnsdomainkeyname', hide);
991
		hideInput('ddnsdomainkey', hide);
992
		hideInput('ddnsclientupdates', hide);
993
		hideCheckbox('ddnsreverse', hide);
994
	}
995

    
996
	// Make the 'Copy My MAC' button a plain button, not a submit button
997
	$("#btnmymac").prop('type','button');
998

    
999
	// On click, copy the hidden 'mymac' text to the 'mac' input
1000
	$("#btnmymac").click(function() {
1001
		$('#mac').val('<?=$mymac?>');
1002
	});
1003

    
1004
	// Make the 'tftp' button a plain button, not a submit button
1005
	$("#btntftp").prop('type','button');
1006

    
1007
	// Show tftp controls
1008
	$("#btntftp").click(function() {
1009
		hideInput('tftp', false);
1010
	});
1011

    
1012
	// Make the 'ntp' button a plain button, not a submit button
1013
	$("#btnntp").prop('type','button');
1014

    
1015
	// Show ntp controls
1016
	$("#btnntp").click(function() {
1017
		hideClass('ntpclass', false);
1018
	});
1019

    
1020
	// Make the 'ddns' button a plain button, not a submit button
1021
	$("#btndyndns").prop('type','button');
1022

    
1023
	// Show ddns controls
1024
	$("#btndyndns").click(function() {
1025
		hideDDNS(false);
1026
	});
1027

    
1028
	// Make the 'ldap' button a plain button, not a submit button
1029
	$("#btnldap").prop('type','button');
1030

    
1031
	// Show ldap controls
1032
	$("#btnldap").click(function() {
1033
		hideInput('ldap', false);
1034
	});
1035

    
1036
	// Make the 'netboot' button a plain button, not a submit button
1037
	$("#btnnetboot").prop('type','button');
1038

    
1039
	// Show netboot controls
1040
	$("#btnnetboot").click(function() {
1041
		hideInput('bootfile_url', false);
1042
		hideCheckbox('shownetboot', false);
1043
	});
1044

    
1045
	// Make the 'additional options' button a plain button, not a submit button
1046
	$("#btnadnl").prop('type','button');
1047

    
1048
	// Show additional  controls
1049
	$("#btnadnl").click(function() {
1050
		hideClass('adnloptions', false);
1051
		hideInput('btnaddopt', false);
1052
	});
1053

    
1054
	// On initial load
1055
	hideDDNS(true);
1056
	hideClass('ntpclass', true);
1057
	hideInput('tftp', true);
1058
	hideInput('ldap', true);
1059
	hideInput('bootfile_url', true);
1060
	hideCheckbox('shownetboot', true);
1061
	hideClass('adnloptions', <?php echo json_encode($noopts); ?>);
1062
	hideInput('btnaddopt', true);
1063
});
1064
//]]>
1065
</script>
1066

    
1067
<?php include('foot.inc');
(121-121/229)