Projet

Général

Profil

Télécharger (75,6 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / services.inc @ d629f1ca

1 17f6eafa Scott Ullrich
<?php
2 5b237745 Scott Ullrich
/*
3
	services.inc
4 5721595b Chris Buechler
	part of the pfSense project (https://www.pfsense.org)
5 a25183c5 Scott Ullrich
6 417fc5c4 Scott Ullrich
	originally part of m0n0wall (http://m0n0.ch/wall)
7 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8 786ff5eb phildd
	Copyright (C) 2010	Ermal Luci
9 5b237745 Scott Ullrich
	All rights reserved.
10 a25183c5 Scott Ullrich
11 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13 a25183c5 Scott Ullrich
14 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16 a25183c5 Scott Ullrich
17 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
18
	   notice, this list of conditions and the following disclaimer in the
19
	   documentation and/or other materials provided with the distribution.
20 a25183c5 Scott Ullrich
21 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
	POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33 523855b0 Scott Ullrich
/*
34 05c4bfa0 Ermal
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/bin/pgrep	/bin/sh	/usr/local/sbin/dhcpd	/usr/local/sbin/igmpproxy
35 1944af41 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig		/usr/local/sbin/dnsmasq
36 950c9a18 Warren Baker
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/miniupnpd	/usr/sbin/radvd
37 1944af41 Ermal
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/dhcleases6	/usr/sbin/bsnmpd
38 523855b0 Scott Ullrich
	pfSense_MODULE:	utils
39
*/
40
41 2206f1b9 Mathias Andersson
define('DYNDNS_PROVIDER_VALUES', 'dnsomatic dyndns dyndns-static dyndns-custom dhs dyns easydns noip noip-free ods zoneedit loopia freedns dnsexit opendns namecheap he-net he-net-v6 he-net-tunnelbroker selfhost route53 cloudflare custom custom-v6 eurodns gratisdns ovh-dynhost citynetwork');
42
define('DYNDNS_PROVIDER_DESCRIPTIONS', 'DNS-O-Matic,DynDNS (dynamic),DynDNS (static),DynDNS (custom),DHS,DyNS,easyDNS,No-IP,No-IP (free),ODS.org,ZoneEdit,Loopia,freeDNS,DNSexit,OpenDNS,Namecheap,HE.net,HE.net (v6),HE.net Tunnelbroker,SelfHost,Route 53,CloudFlare,Custom,Custom (v6),Euro Dns,GratisDNS,OVH DynHOST,City Network');
43 0e3aeb6b Phil Davis
44 d57293a4 Seth Mos
/* implement ipv6 route advertising deamon */
45 92977616 Ermal
function services_radvd_configure($blacklist = array()) {
46 d57293a4 Seth Mos
	global $config, $g;
47 3f9cc8e4 smos
	
48
	if ($g['platform'] == 'jail') 
49 7734aea6 Andrew Thompson
		return;
50
51 d57293a4 Seth Mos
	if(isset($config['system']['developerspew'])) {
52
		$mt = microtime();
53 3f9cc8e4 smos
		echo "services_radvd_configure() being called $mt\n";
54 d57293a4 Seth Mos
	}
55
56
	if (!is_array($config['dhcpdv6']))
57
		$config['dhcpdv6'] = array();
58
59
	$Iflist = get_configured_interface_list();
60 e9ab2ddb smos
	$Iflist = array_merge($Iflist, get_configured_pppoe_server_interfaces());
61 abdd01f5 Ermal
	$carplist = get_configured_carp_interface_list();
62 d57293a4 Seth Mos
63 3f9cc8e4 smos
	$radvdconf = "# Automatically Generated, do not edit\n";
64 4a3ff493 Seth Mos
65 753bd64d Seth Mos
	/* Process all links which need the router advertise daemon */
66 3f9cc8e4 smos
	$radvdifs = array();
67 668e8961 smos
68 3f9cc8e4 smos
	/* handle manually configured DHCP6 server settings first */
69 dfac167c Ermal
	foreach ($config['dhcpdv6'] as $dhcpv6if => $dhcpv6ifconf) {
70
		if (!is_array($config['interfaces'][$dhcpv6if]))
71
			continue;
72
		if (!isset($config['interfaces'][$dhcpv6if]['enable']))
73 d7d2dc52 smos
			continue;
74 5078cd76 smos
75 92977616 Ermal
		/* Do not put in the config an interface which is down */
76
		if (isset($blacklist[$dhcpv6if]))
77
			continue;
78 abdd01f5 Ermal
		if (!isset($dhcpv6ifconf['ramode']))
79 8ca73e85 smos
			$dhcpv6ifconf['ramode'] = $dhcpv6ifconf['mode'];
80
81 3f9cc8e4 smos
		/* are router advertisements enabled? */
82 abdd01f5 Ermal
		if ($dhcpv6ifconf['ramode'] == "disabled")
83 361bb4a9 smos
			continue;
84 d57293a4 Seth Mos
85 abdd01f5 Ermal
		if (!isset($dhcpv6ifconf['rapriority']))
86 8ca73e85 smos
			$dhcpv6ifconf['rapriority'] = "medium";
87
88 25d1c6b2 smos
		/* always start with the real parent, we override with the carp if later */
89 83973bfb smos
		$carpif = false;
90 fe838158 smos
		/* check if we need to listen on a CARP interface */
91 dfac167c Ermal
		if (!empty($dhcpv6ifconf['rainterface'])) {
92 abdd01f5 Ermal
			if (!empty($carplist[$dhcpv6ifconf['rainterface']])) {
93
				$dhcpv6if = $dhcpv6ifconf['rainterface'];
94 83973bfb smos
				$carpif = true;
95 fe838158 smos
			}
96
		}
97 5078cd76 smos
98 06886ae3 Ermal
		$realif = get_real_interface($dhcpv6if, "inet6");
99 60c05056 Ermal
		if (isset($radvdifs[$realif]))
100 c18a10cc smos
			continue;
101
102 2626cbd1 Ermal
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
103
		if (!is_ipaddrv6($ifcfgipv6))
104 5078cd76 smos
			continue;
105
106 d57293a4 Seth Mos
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
107
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
108 60c05056 Ermal
		$radvdifs[$realif] = $realif;
109 d57293a4 Seth Mos
110 3f9cc8e4 smos
		$radvdconf .= "# Generated for DHCPv6 Server $dhcpv6if\n";
111
		$radvdconf .= "interface {$realif} {\n";
112
		$radvdconf .= "\tAdvSendAdvert on;\n";
113 8859c0a6 smos
		$radvdconf .= "\tMinRtrAdvInterval 5;\n";
114
		$radvdconf .= "\tMaxRtrAdvInterval 20;\n";
115 a6bc492f Ermal
		$mtu = get_interface_mtu($realif);
116
		if (is_numeric($mtu))
117
			$radvdconf .= "\tAdvLinkMTU {$mtu};\n";
118
		else
119
			$radvdconf .= "\tAdvLinkMTU 1280;\n";
120 3f9cc8e4 smos
		// $radvdconf .= "\tDeprecatePrefix on;\n";
121 fe838158 smos
		switch($dhcpv6ifconf['rapriority']) {
122
			case "low":
123
				$radvdconf .= "\tAdvDefaultPreference low;\n";
124
				break;
125
			case "high":
126
				$radvdconf .= "\tAdvDefaultPreference high;\n";
127 838a1ecb smos
				break;
128
			default:
129
				$radvdconf .= "\tAdvDefaultPreference medium;\n";
130
				break;
131 fe838158 smos
		}
132
		switch($dhcpv6ifconf['ramode']) {
133 656f1763 Seth Mos
			case "managed":
134 3f9cc8e4 smos
			case "assist":
135 8c78e692 plinss
				$radvdconf .= "\tAdvManagedFlag on;\n";
136 3f9cc8e4 smos
				$radvdconf .= "\tAdvOtherConfigFlag on;\n";
137
				break;
138
		}
139
		$radvdconf .= "\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
140 a99b2b08 smos
		if($carpif == true) {
141 83973bfb smos
			$radvdconf .= "\t\tDeprecatePrefix off;\n";
142 a99b2b08 smos
		} else {
143 83973bfb smos
			$radvdconf .= "\t\tDeprecatePrefix on;\n";
144 a99b2b08 smos
		}
145 fe838158 smos
		switch($dhcpv6ifconf['ramode']) {
146 3f9cc8e4 smos
			case "managed":
147
				$radvdconf .= "\t\tAdvOnLink on;\n";
148
				$radvdconf .= "\t\tAdvAutonomous off;\n";
149
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
150 826ac52c smos
				break;
151
			case "router":
152 3f9cc8e4 smos
				$radvdconf .= "\t\tAdvOnLink off;\n";
153
				$radvdconf .= "\t\tAdvAutonomous off;\n";
154
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
155 656f1763 Seth Mos
				break;
156
			case "assist":
157 3f9cc8e4 smos
				$radvdconf .= "\t\tAdvOnLink on;\n";
158
				$radvdconf .= "\t\tAdvAutonomous on;\n";
159
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
160 107e8acc Ovidiu Predescu
				break;
161 3f9cc8e4 smos
			case "unmanaged":
162
				$radvdconf .= "\t\tAdvOnLink on;\n";
163
				$radvdconf .= "\t\tAdvAutonomous on;\n";
164
				$radvdconf .= "\t\tAdvRouterAddr on;\n";
165
				break;				
166 656f1763 Seth Mos
		}
167 3f9cc8e4 smos
		$radvdconf .= "\t};\n";
168
169 abdd01f5 Ermal
		if($carpif === true) {
170 dc131dfe smos
			$radvdconf .= "\troute ::/0 {\n";
171 8859c0a6 smos
			$radvdconf .= "\t\tRemoveRoute off;\n";
172
			$radvdconf .= "\t};\n";
173
		} else {
174 dc131dfe smos
			$radvdconf .= "\troute ::/0 {\n";
175
			$radvdconf .= "\t\tRemoveRoute on;\n";
176 8859c0a6 smos
			$radvdconf .= "\t};\n";
177
		}
178
179 f535d5a0 Seth Mos
		/* add DNS servers */
180 3aa114d5 Seth Mos
		$dnslist = array();
181 3d73a44d Renato Botelho
		if (isset($dhcpv6ifconf['rasamednsasdhcp6']) && is_array($dhcpv6ifconf['dnsserver']) && !empty($dhcpv6ifconf['dnsserver'])) {
182
			foreach($dhcpv6ifconf['dnsserver'] as $server)
183
				if (is_ipaddrv6($server))
184
					$dnslist[] = $server;
185
		} elseif (!isset($dhcpv6ifconf['rasamednsasdhcp6']) && isset($dhcpv6ifconf['radnsserver']) && is_array($dhcpv6ifconf['radnsserver'])) {
186
			foreach($dhcpv6ifconf['radnsserver'] as $server)
187
				if (is_ipaddrv6($server))
188 3aa114d5 Seth Mos
					$dnslist[] = $server;
189 f535d5a0 Seth Mos
		} elseif (isset($config['dnsmasq']['enable'])) {
190 9a933304 smos
			$dnslist[] = get_interface_ipv6($realif);
191 abdd01f5 Ermal
		} elseif (is_array($config['system']['dnsserver']) && !empty($config['system']['dnsserver'])) {
192 3aa114d5 Seth Mos
			foreach($config['system']['dnsserver'] as $server) {
193 abdd01f5 Ermal
				if (is_ipaddrv6($server))
194 3aa114d5 Seth Mos
					$dnslist[] = $server;
195
			}
196
		}
197 abdd01f5 Ermal
		if (count($dnslist) > 0) {
198 3f9cc8e4 smos
			$dnsstring = implode(" ", $dnslist);
199 abdd01f5 Ermal
			if ($dnsstring <> "")
200 6c582308 smos
				$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
201 f535d5a0 Seth Mos
		}
202 abdd01f5 Ermal
		if (!empty($dhcpv6ifconf['domain'])) {
203 6c582308 smos
			$radvdconf .= "\tDNSSL {$dhcpv6ifconf['domain']} { };\n";
204 abdd01f5 Ermal
		} elseif (!empty($config['system']['domain'])) {
205 6c582308 smos
			$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
206 f535d5a0 Seth Mos
		}
207 3f9cc8e4 smos
		$radvdconf .= "};\n";
208 ed395640 Seth Mos
	}
209
210 3f9cc8e4 smos
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
211 ed395640 Seth Mos
	foreach ($Iflist as $if => $ifdescr) {
212 20a7cb15 smos
		if(!isset($config['interfaces'][$if]['track6-interface']))
213 ed395640 Seth Mos
			continue;
214 d7d2dc52 smos
		if(!isset($config['interfaces'][$if]['enable']))
215
			continue;
216 92977616 Ermal
		/* Do not put in the config an interface which is down */
217
		if (isset($blacklist[$if]))
218
			continue;
219 60c05056 Ermal
		$trackif = $config['interfaces'][$if]['track6-interface'];
220
		if (empty($config['interfaces'][$trackif]))
221
			continue;
222
223 06886ae3 Ermal
		$realif = get_real_interface($if, "inet6");
224 3f9cc8e4 smos
		/* prevent duplicate entries, manual overrides */
225 60c05056 Ermal
		if (isset($radvdifs[$realif]))
226 7492f21d smos
			continue;
227
228 ed395640 Seth Mos
		$ifcfgipv6 = get_interface_ipv6($if);
229 75aec77a Ermal
		if(!is_ipaddrv6($ifcfgipv6)) {
230
			$subnetv6 = "::";
231
			$ifcfgsnv6 = "64";
232
		} else {
233
			$ifcfgsnv6 = get_interface_subnetv6($if);
234
			$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
235
		}
236 60c05056 Ermal
		$radvdifs[$realif] = $realif;
237 c18a10cc smos
238 20a7cb15 smos
		$autotype = $config['interfaces'][$trackif]['ipaddrv6'];
239
	
240 dfac167c Ermal
		if ($g['debug'])
241
			log_error("configuring RA on {$if} for type {$autotype} radvd subnet {$subnetv6}/{$ifcfgsnv6}");
242 668e8961 smos
243 60c05056 Ermal
		$radvdconf .= "# Generated config for {$autotype} delegation from {$trackif} on {$if}\n";
244
		$radvdconf .= "interface {$realif} {\n";
245
		$radvdconf .= "\tAdvSendAdvert on;\n";
246
		$radvdconf .= "\tMinRtrAdvInterval 3;\n";
247
		$radvdconf .= "\tMaxRtrAdvInterval 10;\n";
248
		$mtu = get_interface_mtu($realif);
249
		if (is_numeric($mtu))
250
			$radvdconf .= "\tAdvLinkMTU {$mtu};\n";
251
		else
252
			$radvdconf .= "\tAdvLinkMTU 1280;\n";
253
		$radvdconf .= "\tAdvOtherConfigFlag on;\n";
254
		$radvdconf .= "\t\tprefix {$subnetv6}/{$ifcfgsnv6} {\n";
255
		$radvdconf .= "\t\tAdvOnLink on;\n";
256
		$radvdconf .= "\t\tAdvAutonomous on;\n";
257
		$radvdconf .= "\t\tAdvRouterAddr on;\n";
258
		$radvdconf .= "\t};\n";
259
260
		/* add DNS servers */
261 668e8961 smos
		$dnslist = array();
262 60c05056 Ermal
		if (isset($config['dnsmasq']['enable'])) {
263
			$dnslist[] = $ifcfgipv6;
264
		} elseif (is_array($config['system']['dnsserver']) && !empty($config['system']['dnsserver'])) {
265
			foreach($config['system']['dnsserver'] as $server) {
266
				if(is_ipaddrv6($server))
267
					$dnslist[] = $server;
268
			}
269 668e8961 smos
		}
270 60c05056 Ermal
		if (count($dnslist) > 0) {
271
			$dnsstring = implode(" ", $dnslist);
272
			if (!empty($dnsstring))
273
				$radvdconf .= "\tRDNSS {$dnsstring} { };\n";
274
		}
275
		if (!empty($config['system']['domain'])) {
276
			$radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n";
277
		}
278
		$radvdconf .= "};\n";
279 668e8961 smos
	}
280
281 928d4416 Ermal
	/* write radvd.conf */
282 abdd01f5 Ermal
	if (!@file_put_contents("{$g['varetc_path']}/radvd.conf", $radvdconf)) {
283
		log_error("Error: cannot open radvd.conf in services_radvd_configure().\n");
284
		if ($g['booting'])
285
			printf("Error: cannot open radvd.conf in services_radvd_configure().\n");
286
	}
287 928d4416 Ermal
	unset($radvdconf);
288 d57293a4 Seth Mos
289 abdd01f5 Ermal
	if (count($radvdifs) > 0) {
290
		if (isvalidpid("{$g['varrun_path']}/radvd.pid"))
291
			sigkillbypid("{$g['varrun_path']}/radvd.pid", "HUP");
292
		else
293
			mwexec("/usr/local/sbin/radvd -p {$g['varrun_path']}/radvd.pid -C {$g['varetc_path']}/radvd.conf -m syslog");
294 6afeb202 smos
	} else {
295
		/* we need to shut down the radvd cleanly, it will send out the prefix
296
		 * information with a lifetime of 0 to notify clients of a (possible) new prefix */
297 abdd01f5 Ermal
		if (isvalidpid("{$g['varrun_path']}/radvd.pid")) {
298 6afeb202 smos
			log_error("Shutting down Router Advertisment daemon cleanly");
299 abdd01f5 Ermal
			killbypid("{$g['varrun_path']}/radvd.pid");
300 dfac167c Ermal
			@unlink("{$g['varrun_path']}/radvd.pid");
301 6afeb202 smos
		}
302 d57293a4 Seth Mos
	}
303
	return 0;
304
}
305
306 92977616 Ermal
function services_dhcpd_configure($family = "all", $blacklist = array()) {
307 f19d3b7a Scott Ullrich
	global $config, $g;
308 2fb056d8 Seth Mos
309
	/* configure DHCPD chroot once */
310
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
311 d6c82882 Ermal
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}\n");
312
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
313
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
314
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
315
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
316
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
317
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
318
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
319
	fwrite($fd, "/bin/mkdir -p {$g['dhcpd_chroot_path']}/run\n");
320
	fwrite($fd, "/usr/sbin/chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
321 06886ae3 Ermal
	fwrite($fd, "/bin/cp -n /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
322
	fwrite($fd, "/bin/cp -n /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
323 60214e06 bcyrill
	fwrite($fd, "/bin/chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
324 d6c82882 Ermal
325
	$status = `/sbin/mount | /usr/bin/grep -v grep  | /usr/bin/grep  "{$g['dhcpd_chroot_path']}/dev"`;
326
	if (!trim($status))
327
		fwrite($fd, "/sbin/mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
328 2fb056d8 Seth Mos
	fclose($fd);
329
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
330
331 3084ba6e Ermal
	if ($family == "all" || $family == "inet")
332
		services_dhcpdv4_configure();
333
	if ($family == "all" || $family == "inet6") {
334 92977616 Ermal
		services_dhcpdv6_configure($blacklist);
335
		services_radvd_configure($blacklist);
336 3084ba6e Ermal
	}
337 2fb056d8 Seth Mos
}
338 1c903aa4 Ermal
339 2fb056d8 Seth Mos
function services_dhcpdv4_configure() {
340
	global $config, $g;
341 3df2dbfd jim-p
	$need_ddns_updates = false;
342
	$ddns_zones = array();
343 107e8acc Ovidiu Predescu
344
	if($g['services_dhcp_server_enable'] == false)
345 e3a13b00 Scott Ullrich
		return;
346
347 58c7450e Scott Ullrich
	if(isset($config['system']['developerspew'])) {
348 acd910bf Scott Ullrich
		$mt = microtime();
349 2fb056d8 Seth Mos
		echo "services_dhcpdv4_configure($if) being called $mt\n";
350 acd910bf Scott Ullrich
	}
351 107e8acc Ovidiu Predescu
352 af25d415 Chris Buechler
	/* kill any running dhcpd */
353 abdd01f5 Ermal
	if (isvalidpid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid"))
354 ed395640 Seth Mos
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
355 a25183c5 Scott Ullrich
356 15be1722 Ermal Luçi
	/* DHCP enabled on any interfaces? */
357
	if (!is_dhcp_server_enabled())
358
		return 0;
359
360 48ab0cd2 Scott Ullrich
	/* if OLSRD is enabled, allow WAN to house DHCP. */
361 c7f44ae0 Scott Ullrich
	if($config['installedpackages']['olsrd'])
362
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
363
				if($olsrd['enable'])
364 48ab0cd2 Scott Ullrich
					$is_olsr_enabled = true;
365
366 381e43e0 jim-p
	if ($g['booting']) {
367 e92e83d4 jim-p
		/* restore the leases, if we have them */
368
		if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
369
			$dhcprestore = "";
370
			$dhcpreturn = "";
371
			exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
372
			$dhcprestore = implode(" ", $dhcprestore);
373
			if($dhcpreturn <> 0) {
374
				log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n"));
375 381e43e0 jim-p
			}
376
		}
377 e92e83d4 jim-p
		/* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */
378
		if (($g['platform'] == "pfSense") && !isset($config['system']['use_mfs_tmpvar'])) {
379
			unlink_if_exists("{$g['cf_conf_path']}/dhcpleases.tgz");
380
		}
381 381e43e0 jim-p
	}
382
383 5b237745 Scott Ullrich
	$syscfg = $config['system'];
384 a8a98fb4 Seth Mos
	if (!is_array($config['dhcpd']))
385
		$config['dhcpd'] = array();
386 d57293a4 Seth Mos
	$dhcpdcfg = $config['dhcpd'];
387 6f9b8073 Ermal Luçi
	$Iflist = get_configured_interface_list();
388 107e8acc Ovidiu Predescu
389 3ad6b569 Phil Davis
	/* Only consider DNS servers with IPv4 addresses for the IPv4 DHCP server. */
390
	$dns_arrv4 = array();
391 68169a55 jim-p
	if (is_array($syscfg['dnsserver'])) {
392
		foreach($syscfg['dnsserver'] as $dnsserver) {
393
			if (is_ipaddrv4($dnsserver)) {
394
				$dns_arrv4[] = $dnsserver;
395
			}
396 3ad6b569 Phil Davis
		}
397
	}
398
399 5b237745 Scott Ullrich
	if ($g['booting'])
400 f1a44a3a Carlos Eduardo Ramos
		echo gettext("Starting DHCP service...");
401 5b237745 Scott Ullrich
	else
402
		sleep(1);
403 a25183c5 Scott Ullrich
404 518030b3 Scott Ullrich
	$custoptions = "";
405 107e8acc Ovidiu Predescu
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
406 c71f5fcd Ermal
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
407 5ac2f583 Ermal
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
408 678dfd0f Erik Fonnesbeck
				if(!empty($item['type']))
409
					$itemtype = $item['type'];
410
				else
411
					$itemtype = "text";
412
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
413 518030b3 Scott Ullrich
			}
414
		}
415
	}
416 4cab31d0 Scott Ullrich
417 5b237745 Scott Ullrich
	$dhcpdconf = <<<EOD
418 107e8acc Ovidiu Predescu
419 5b237745 Scott Ullrich
option domain-name "{$syscfg['domain']}";
420 6c23757b Martin Fuchs
option ldap-server code 95 = text;
421 9be23653 Martin Fuchs
option domain-search-list code 119 = text;
422 fdb116a9 Donald A. Cupp Jr
option arch code 93 = unsigned integer 16; # RFC4578
423 518030b3 Scott Ullrich
{$custoptions}
424 5b237745 Scott Ullrich
default-lease-time 7200;
425
max-lease-time 86400;
426
log-facility local7;
427 175fe82b Scott Ullrich
one-lease-per-client true;
428 436a0f50 Scott Ullrich
deny duplicates;
429 9c88328f Scott Ullrich
ping-check true;
430 87019fc4 Andres Petralli
update-conflict-detection false;
431 5b237745 Scott Ullrich
432
EOD;
433 a25183c5 Scott Ullrich
434 d8912c6b Chris Buechler
	if(!isset($dhcpifconf['disableauthoritative']))
435
		$dhcpdconf .= "authoritative;\n";
436
437 107e8acc Ovidiu Predescu
	if(isset($dhcpifconf['alwaysbroadcast']))
438 5252b98d Scott Ullrich
		$dhcpdconf .= "always-broadcast on\n";
439
440 5b237745 Scott Ullrich
	$dhcpdifs = array();
441 c08a5659 smos
	$add_routers = false;
442
	$gateways_arr = return_gateways_array();
443
	/* only add a routers line if the system has any IPv4 gateway at all */
444
	/* a static route has a gateway, manually overriding this field always works */
445
	foreach($gateways_arr as $gwitem) {
446
		if($gwitem['ipprotocol'] == "inet") {
447
			$add_routers = true;
448
			break;
449
		}
450
	}
451 c7f44ae0 Scott Ullrich
452 4494cf6a Chris Buechler
	/*    loop through and determine if we need to setup
453 8fa56d1f Scott Ullrich
	 *    failover peer "bleh" entries
454
	 */
455
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
456 53f32329 Scott Ullrich
457 09f11c71 jim-p
		interfaces_staticarp_configure($dhcpif);
458
459 6f9b8073 Ermal Luçi
		if (!isset($dhcpifconf['enable']))
460
			continue;
461
462 8fa56d1f Scott Ullrich
		if($dhcpifconf['failover_peerip'] <> "") {
463 a01f8bfc Ermal
			$intip = get_interface_ip($dhcpif);
464 8fa56d1f Scott Ullrich
			/*
465
			 *    yep, failover peer is defined.
466
			 *    does it match up to a defined vip?
467
			 */
468 d2edbd8a Scott Ullrich
			$skew = 110;
469 9d7ca11f Ermal
			if(is_array($config['virtualip']['vip'])) {
470
				foreach ($config['virtualip']['vip'] as $vipent) {
471 a01f8bfc Ermal
					if($vipent['interface'] == $dhcpif) {
472
						$carp_nw = gen_subnet($vipent['subnet'], $vipent['subnet_bits']);
473
						if (ip_in_subnet($dhcpifconf['failover_peerip'], "{$carp_nw}/{$vipent['subnet_bits']}")) {
474
							/* this is the interface! */
475
							if(is_numeric($vipent['advskew']) && (intval($vipent['advskew']) < 20)) {
476
								$skew = 0;
477
								break;
478
							}
479
						}
480 6181b36f Scott Ullrich
					}
481 8fa56d1f Scott Ullrich
				}
482 25066204 Scott Ullrich
			} else {
483 959dc96b Chris Buechler
				log_error(gettext("Warning!  DHCP Failover setup and no CARP virtual IPs defined!"));
484 8fa56d1f Scott Ullrich
			}
485 5e390f54 Scott Ullrich
			if($skew > 10) {
486 8fa56d1f Scott Ullrich
				$type = "secondary";
487 0e93097a Scott Ullrich
				$my_port = "520";
488
				$peer_port = "519";
489 8fa56d1f Scott Ullrich
			} else {
490 0e93097a Scott Ullrich
				$my_port = "519";
491
				$peer_port = "520";
492 8fa56d1f Scott Ullrich
				$type = "primary";
493 4d3ff974 Scott Ullrich
				$dhcpdconf_pri  = "split 128;\n";
494 1a0bb737 Scott Ullrich
				$dhcpdconf_pri .= "  mclt 600;\n";
495 8fa56d1f Scott Ullrich
			}
496 a01f8bfc Ermal
497
			if (is_ipaddrv4($intip)) {
498 8fa56d1f Scott Ullrich
			$dhcpdconf .= <<<EOPP
499 d5e4f7c9 jim-p
failover peer "dhcp_{$dhcpif}" {
500 8fa56d1f Scott Ullrich
  {$type};
501
  address {$intip};
502 0e93097a Scott Ullrich
  port {$my_port};
503 8fa56d1f Scott Ullrich
  peer address {$dhcpifconf['failover_peerip']};
504 0e93097a Scott Ullrich
  peer port {$peer_port};
505 2cd5ce14 Scott Ullrich
  max-response-delay 10;
506 b865d178 Scott Ullrich
  max-unacked-updates 10;
507
  {$dhcpdconf_pri}
508 b259d1c6 Scott Ullrich
  load balance max seconds 3;
509 8fa56d1f Scott Ullrich
}
510 959dc96b Chris Buechler
\n
511 8fa56d1f Scott Ullrich
EOPP;
512 a01f8bfc Ermal
			}
513 8fa56d1f Scott Ullrich
		}
514
	}
515
516 5b237745 Scott Ullrich
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
517 a25183c5 Scott Ullrich
518 3df2dbfd jim-p
		$newzone = array();
519 5b237745 Scott Ullrich
		$ifcfg = $config['interfaces'][$dhcpif];
520 a25183c5 Scott Ullrich
521 6f9b8073 Ermal Luçi
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
522 5b237745 Scott Ullrich
			continue;
523 a55e9c70 Ermal Lu?i
		$ifcfgip = get_interface_ip($dhcpif);
524
		$ifcfgsn = get_interface_subnet($dhcpif);
525
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
526
		$subnetmask = gen_subnet_mask($ifcfgsn);
527 a25183c5 Scott Ullrich
528 85e3f445 Ermal
		if (!is_ipaddr($subnet))
529
			continue;
530
531 48ab0cd2 Scott Ullrich
		if($is_olsr_enabled == true)
532 c7f44ae0 Scott Ullrich
			if($dhcpifconf['netmask'])
533 9a537862 Scott Ullrich
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
534 48ab0cd2 Scott Ullrich
535 cba980f6 jim-p
		$all_pools = array();
536
		$all_pools[] = $dhcpifconf;
537
		if (is_array($dhcpifconf['pool'])) {
538
			$all_pools = array_merge($all_pools, $dhcpifconf['pool']);
539
		}
540
541 5b237745 Scott Ullrich
		$dnscfg = "";
542 a25183c5 Scott Ullrich
543 5b237745 Scott Ullrich
		if ($dhcpifconf['domain']) {
544
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
545
		}
546 107e8acc Ovidiu Predescu
547 84931046 jim-p
		if($dhcpifconf['domainsearchlist'] <> "") {
548 a3de8b9e Pierre POMES
			$dnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpifconf['domainsearchlist'])) . "\";\n";
549 84931046 jim-p
		}
550 9be23653 Martin Fuchs
551 4e9cd828 Seth Mos
		if (isset($dhcpifconf['ddnsupdate'])) {
552 3df2dbfd jim-p
			$need_ddns_updates = true;
553
			$newzone = array();
554 4e9cd828 Seth Mos
			if($dhcpifconf['ddnsdomain'] <> "") {
555 3df2dbfd jim-p
				$newzone['domain-name'] = $dhcpifconf['ddnsdomain'];
556 4e9cd828 Seth Mos
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
557 3df2dbfd jim-p
			} else {
558
				$newzone['domain-name'] = $config['system']['domain'];
559
			}
560
			$revsubnet = explode(".", $subnet);
561
			$revsubnet = array_reverse($revsubnet);
562
			foreach ($revsubnet as $octet) {
563
				if ($octet != "0")
564
					break;
565
				array_shift($revsubnet);
566 4e9cd828 Seth Mos
			}
567 3df2dbfd jim-p
			$newzone['ptr-domain'] = implode(".", $revsubnet) . ".in-addr.arpa";
568 4e9cd828 Seth Mos
		}
569
570 aff9d6ab Scott Ullrich
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
571 8ee01642 Scott Ullrich
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
572 3df2dbfd jim-p
			if ($newzone['domain-name'])
573
				$newzone['dns-servers'] = $dhcpifconf['dnsserver'];
574 aff9d6ab Scott Ullrich
		} else if (isset($config['dnsmasq']['enable'])) {
575 a55e9c70 Ermal Lu?i
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
576 3df2dbfd jim-p
			if ($newzone['domain-name'] && is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0]))
577
				$newzone['dns-servers'] = $syscfg['dnsserver'];
578 3ad6b569 Phil Davis
		} else if (!empty($dns_arrv4)) {
579
			$dnscfg .= "	option domain-name-servers " . join(",", $dns_arrv4) . ";";
580 3df2dbfd jim-p
			if ($newzone['domain-name'])
581 3ad6b569 Phil Davis
				$newzone['dns-servers'] = $dns_arrv4;
582 aff9d6ab Scott Ullrich
		}
583
584 cba980f6 jim-p
		/* Create classes - These all contain comma separated lists. Join them into one 
585
		   big comma separated string then split them all up. */
586
		$all_mac_strings = array();
587
		if (is_array($dhcpifconf['pool'])) {
588
			foreach($all_pools as $poolconf) {
589
				$all_mac_strings[] = $poolconf['mac_allow'];
590
				$all_mac_strings[] = $poolconf['mac_deny'];
591
			}
592
		}
593
		$all_mac_strings[] = $dhcpifconf['mac_allow'];
594
		$all_mac_strings[] = $dhcpifconf['mac_deny'];
595
		$all_mac_list = array_unique(explode(',', implode(',', $all_mac_strings)));
596 1f1a08c8 jim-p
		foreach ($all_mac_list as $mac) {
597 80d30a83 jim-p
			if (empty($mac))
598
				continue;
599 1f1a08c8 jim-p
			$dhcpdconf .= 'class "' . str_replace(':', '', $mac) . '" {' . "\n";
600 140f30ea jim-p
			// Skip the first octet of the MAC address - for media type, typically Ethernet ("01") and match the rest.
601 1f1a08c8 jim-p
			$dhcpdconf .= '	match if substring (hardware, 1, ' . (substr_count($mac, ':') + 1) . ') = ' . $mac . ';' . "\n";
602
			$dhcpdconf .= '}' . "\n";
603
		}
604
605 85e3f445 Ermal
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
606 c7f44ae0 Scott Ullrich
607 cba980f6 jim-p
// Setup pool options
608
		foreach($all_pools as $poolconf) {
609
			$dhcpdconf .= "	pool {\n";
610
			/* is failover dns setup? */
611
			if (is_array($poolconf['dnsserver']) && $poolconf['dnsserver'][0] <> "") {
612
				$dhcpdconf .= "		option domain-name-servers {$poolconf['dnsserver'][0]}";
613
				if($poolconf['dnsserver'][1] <> "")
614
					$dhcpdconf .= ",{$poolconf['dnsserver'][1]}";
615
				$dhcpdconf .= ";\n";
616
			}
617
618
			/* allow/deny MACs */
619
			$mac_allow_list = array_unique(explode(',', $poolconf['mac_allow']));
620
			foreach ($mac_allow_list as $mac) {
621
				if (empty($mac))
622
					continue;
623
				$dhcpdconf .= "		allow members of \"" . str_replace(':', '', $mac) . "\";\n";
624
			}
625
			$mac_deny_list = array_unique(explode(',', $poolconf['mac_deny']));
626
			foreach ($mac_deny_list as $mac) {
627
				if (empty($mac))
628
					continue;
629
				$dhcpdconf .= "		deny members of \"" . str_replace(':', '', $mac) . "\";\n";
630
			}
631
632
			if($poolconf['failover_peerip'] <> "")
633
				$dhcpdconf .= "		deny dynamic bootp clients;\n";
634
635
			if (isset($poolconf['denyunknown']))
636
			   $dhcpdconf .= "		deny unknown-clients;\n";
637
638 4208f7b1 timdufrane
			if ($poolconf['gateway'] && $poolconf['gateway'] != "none" && ($poolconf['gateway'] != $dhcpifconf['gateway']))
639 f9f6f7d4 jim-p
				$dhcpdconf .= "		option routers {$poolconf['gateway']};\n";
640 cba980f6 jim-p
641
			if($dhcpifconf['failover_peerip'] <> "") {
642 d5e4f7c9 jim-p
				$dhcpdconf .= "		failover peer \"dhcp_{$dhcpif}\";\n";
643 cba980f6 jim-p
			}
644
645
			$pdnscfg = "";
646
647
			if ($poolconf['domain'] && ($poolconf['domain'] != $dhcpifconf['domain'])) {
648
				$pdnscfg .= "		option domain-name \"{$poolconf['domain']}\";\n";
649
			}
650
651
			if(!empty($poolconf['domainsearchlist']) && ($poolconf['domainsearchlist'] != $dhcpifconf['domainsearchlist'])) {
652
				$pdnscfg .= "		option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $poolconf['domainsearchlist'])) . "\";\n";
653
			}
654
655 7309ff39 Renato Botelho
			if (isset($poolconf['ddnsupdate'])) {
656
				if (($poolconf['ddnsdomain'] <> "") && ($poolconf['ddnsdomain'] != $dhcpifconf['ddnsdomain']))
657 cba980f6 jim-p
					$pdnscfg .= "		ddns-domainname \"{$poolconf['ddnsdomain']}\";\n";
658
				$pdnscfg .= "		ddns-update-style interim;\n";
659
			}
660
661 fa7b825f Renato Botelho
			if (is_array($poolconf['dnsserver']) && ($poolconf['dnsserver'][0]) && ($poolconf['dnsserver'][0] != $dhcpifconf['dnsserver'][0])) {
662 cba980f6 jim-p
				$pdnscfg .= "		option domain-name-servers " . join(",", $poolconf['dnsserver']) . ";\n";
663
			}
664
			$dhcpdconf .= "{$pdnscfg}";
665 1f1a08c8 jim-p
666 cba980f6 jim-p
			// default-lease-time
667
			if ($poolconf['defaultleasetime'] && ($poolconf['defaultleasetime'] != $dhcpifconf['defaultleasetime']))
668
				$dhcpdconf .= "		default-lease-time {$poolconf['defaultleasetime']};\n";
669
670
			// max-lease-time
671
			if ($poolconf['maxleasetime'] && ($poolconf['maxleasetime'] != $dhcpifconf['maxleasetime']))
672
				$dhcpdconf .= "		max-lease-time {$poolconf['maxleasetime']};\n";
673
674
			// netbios-name*
675 fa7b825f Renato Botelho
			if (is_array($poolconf['winsserver']) && $poolconf['winsserver'][0] && ($poolconf['winsserver'][0] != $dhcpifconf['winsserver'][0])) {
676 cba980f6 jim-p
				$dhcpdconf .= "		option netbios-name-servers " . join(",", $poolconf['winsserver']) . ";\n";
677
				$dhcpdconf .= "		option netbios-node-type 8;\n";
678
			}
679 c7f44ae0 Scott Ullrich
680 cba980f6 jim-p
			// ntp-servers
681 fa7b825f Renato Botelho
			if (is_array($poolconf['ntpserver']) && $poolconf['ntpserver'][0] && ($poolconf['ntpserver'][0] != $dhcpifconf['ntpserver'][0]))
682 cba980f6 jim-p
				$dhcpdconf .= "		option ntp-servers " . join(",", $poolconf['ntpserver']) . ";\n";
683
684
			// tftp-server-name
685
			if (!empty($poolconf['tftp']) && ($poolconf['tftp'] != $dhcpifconf['tftp']))
686
				$dhcpdconf .= "		option tftp-server-name \"{$poolconf['tftp']}\";\n";
687
688
			// ldap-server
689
			if (!empty($poolconf['ldap']) && ($poolconf['ldap'] != $dhcpifconf['ldap']))
690
				$dhcpdconf .= "		option ldap-server \"{$poolconf['ldap']}\";\n";
691
692
			// net boot information
693
			if(isset($poolconf['netboot'])) {
694
				if (!empty($poolconf['nextserver']) && ($poolconf['nextserver'] != $dhcpifconf['nextserver'])) {
695
					$dhcpdconf .= "		next-server {$poolconf['nextserver']};\n";
696
				}
697
				if (!empty($poolconf['filename']) && ($poolconf['filename'] != $dhcpifconf['filename'])) {
698
					$dhcpdconf .= "		filename \"{$poolconf['filename']}\";\n";
699
				}
700
				if (!empty($poolconf['rootpath']) && ($poolconf['rootpath'] != $dhcpifconf['rootpath'])) {
701
					$dhcpdconf .= "		option root-path \"{$poolconf['rootpath']}\";\n";
702
				}
703
			}
704
			$dhcpdconf .= "		range {$poolconf['range']['from']} {$poolconf['range']['to']};\n";
705
			$dhcpdconf .= "	}\n\n";
706
		}
707
// End of settings inside pools
708 a25183c5 Scott Ullrich
709 4208f7b1 timdufrane
		if ($dhcpifconf['gateway'] && $dhcpifconf['gateway'] != "none") {
710 5b237745 Scott Ullrich
			$routers = $dhcpifconf['gateway'];
711 c08a5659 smos
			$add_routers = true;
712 4208f7b1 timdufrane
		} elseif ($dhcpifconf['gateway'] == "none") {
713
			$add_routers = false;
714 c08a5659 smos
		} else {
715 a55e9c70 Ermal Lu?i
			$routers = $ifcfgip;
716 c08a5659 smos
		}
717
		if($add_routers)
718
			$dhcpdconf .= "	option routers {$routers};\n";
719 cba980f6 jim-p
720 c08a5659 smos
		$dhcpdconf .= <<<EOD
721 5b237745 Scott Ullrich
$dnscfg
722
723
EOD;
724 693833cb Seth Mos
    		// default-lease-time
725 518030b3 Scott Ullrich
		if ($dhcpifconf['defaultleasetime'])
726 5b237745 Scott Ullrich
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
727 518030b3 Scott Ullrich
728
		// max-lease-time
729 5b237745 Scott Ullrich
		if ($dhcpifconf['maxleasetime'])
730
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
731 a25183c5 Scott Ullrich
732 518030b3 Scott Ullrich
		// netbios-name*
733 5b237745 Scott Ullrich
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
734
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
735
			$dhcpdconf .= "	option netbios-node-type 8;\n";
736
		}
737 a25183c5 Scott Ullrich
738 518030b3 Scott Ullrich
		// ntp-servers
739 ad171999 Seth Mos
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
740
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
741
742 518030b3 Scott Ullrich
		// tftp-server-name
743 ee1b024e Martin Fuchs
		if ($dhcpifconf['tftp'] <> "")
744 6c23757b Martin Fuchs
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
745
746 518030b3 Scott Ullrich
		// Handle option, number rowhelper values
747
		$dhcpdconf .= "\n";
748
		if($dhcpifconf['numberoptions']['item']) {
749 5ac2f583 Ermal
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
750 678dfd0f Erik Fonnesbeck
				if(empty($item['type']) || $item['type'] == "text")
751
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
752
				else
753
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
754 518030b3 Scott Ullrich
			}
755
		}
756
757
		// ldap-server
758
		if ($dhcpifconf['ldap'] <> "")
759 6c23757b Martin Fuchs
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
760
761 518030b3 Scott Ullrich
		// net boot information
762 4e9cd828 Seth Mos
		if(isset($dhcpifconf['netboot'])) {
763 a2578c27 Anthony Wrather
			if ($dhcpifconf['nextserver'] <> "") {
764
				$dhcpdconf .= "	next-server {$dhcpifconf['nextserver']};\n";
765
			}
766 fdb116a9 Donald A. Cupp Jr
			if (!empty($dhcpifconf['filename']) && !empty($dhcpifconf['filename32']) && !empty($dhcpifconf['filename64'])) {
767
				$dhcpdconf .= "	if option arch = 00:06 {\n";
768
				$dhcpdconf .= "		filename \"{$dhcpifconf['filename32']}\";\n";
769
				$dhcpdconf .= "	} else if option arch = 00:07 {\n";
770
				$dhcpdconf .= "		filename \"{$dhcpifconf['filename64']}\";\n";
771
				$dhcpdconf .= "	} else {\n";
772
				$dhcpdconf .= "		filename \"{$dhcpifconf['filename']}\";\n";
773
				$dhcpdconf .= "	}\n\n";
774
			} elseif (!empty($dhcpifconf['filename'])) {
775 4e9cd828 Seth Mos
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
776
			}
777 fdb116a9 Donald A. Cupp Jr
			if (!empty($dhcpifconf['rootpath'])) {
778 ca126e03 Martin Fuchs
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
779 cba980f6 jim-p
			}
780 4e9cd828 Seth Mos
		}
781 107e8acc Ovidiu Predescu
782 5b237745 Scott Ullrich
		$dhcpdconf .= <<<EOD
783
}
784
785
EOD;
786
787
		/* add static mappings */
788
		if (is_array($dhcpifconf['staticmap'])) {
789 a25183c5 Scott Ullrich
790 5b237745 Scott Ullrich
			$i = 0;
791
			foreach ($dhcpifconf['staticmap'] as $sm) {
792 449f1dd2 Will Boyce
				$dhcpdconf .= "host s_{$dhcpif}_{$i} {\n";
793
794
                if ($sm['mac'])
795
                    $dhcpdconf .= "        hardware ethernet {$sm['mac']};\n";
796
797
                if ($sm['cid'])
798
                    $dhcpdconf .= "        option dhcp-client-identifier \"{$sm['cid']}\";\n";
799 5b237745 Scott Ullrich
800
				if ($sm['ipaddr'])
801
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
802 a25183c5 Scott Ullrich
803 ad30055f Ermal Lu?i
				if ($sm['hostname']) {
804
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
805 46c5b763 pierrepomes
					$dhhostname = str_replace(".", "_", $dhhostname);
806 2f590513 smos
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
807 ad30055f Ermal Lu?i
				}
808 a2578c27 Anthony Wrather
				if ($sm['filename'])
809
					$dhcpdconf .= "	filename \"{$sm['filename']}\";\n";
810
811
				if ($sm['rootpath'])
812
					$dhcpdconf .= "	option root-path \"{$sm['rootpath']}\";\n";
813 80717709 Martin Fuchs
814 7309ff39 Renato Botelho
				if ($sm['gateway'] && ($sm['gateway'] != $dhcpifconf['gateway']))
815
					$dhcpdconf .= "	option routers {$sm['gateway']};\n";
816
817
				$smdnscfg = "";
818
819
				if ($sm['domain'] && ($sm['domain'] != $dhcpifconf['domain'])) {
820
					$smdnscfg .= "	option domain-name \"{$sm['domain']}\";\n";
821
				}
822
823
				if(!empty($sm['domainsearchlist']) && ($sm['domainsearchlist'] != $dhcpifconf['domainsearchlist'])) {
824
					$smdnscfg .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $sm['domainsearchlist'])) . "\";\n";
825
				}
826
827
				if (isset($sm['ddnsupdate'])) {
828
					if (($sm['ddnsdomain'] <> "") && ($sm['ddnsdomain'] != $dhcpifconf['ddnsdomain']))
829
						$pdnscfg .= "		ddns-domainname \"{$sm['ddnsdomain']}\";\n";
830
					$pdnscfg .= "		ddns-update-style interim;\n";
831
				}
832
833
				if (is_array($sm['dnsserver']) && ($sm['dnsserver'][0]) && ($sm['dnsserver'][0] != $dhcpifconf['dnsserver'][0])) {
834
					$smdnscfg .= "	option domain-name-servers " . join(",", $sm['dnsserver']) . ";\n";
835
				}
836
				$dhcpdconf .= "{$smdnscfg}";
837
838
				// default-lease-time
839
				if ($sm['defaultleasetime'] && ($sm['defaultleasetime'] != $dhcpifconf['defaultleasetime']))
840
					$dhcpdconf .= "	default-lease-time {$sm['defaultleasetime']};\n";
841
842
				// max-lease-time
843
				if ($sm['maxleasetime'] && ($sm['maxleasetime'] != $dhcpifconf['maxleasetime']))
844
					$dhcpdconf .= "	max-lease-time {$sm['maxleasetime']};\n";
845
846
				// netbios-name*
847
				if (is_array($sm['winsserver']) && $sm['winsserver'][0] && ($sm['winsserver'][0] != $dhcpifconf['winsserver'][0])) {
848
					$dhcpdconf .= "	option netbios-name-servers " . join(",", $sm['winsserver']) . ";\n";
849
					$dhcpdconf .= "	option netbios-node-type 8;\n";
850
				}
851
852
				// ntp-servers
853
				if (is_array($sm['ntpserver']) && $sm['ntpserver'][0] && ($sm['ntpserver'][0] != $dhcpifconf['ntpserver'][0]))
854
					$dhcpdconf .= "	option ntp-servers " . join(",", $sm['ntpserver']) . ";\n";
855
856
				// tftp-server-name
857
				if (!empty($sm['tftp']) && ($sm['tftp'] != $dhcpifconf['tftp']))
858
					$dhcpdconf .= "	option tftp-server-name \"{$sm['tftp']}\";\n";
859
860 5b237745 Scott Ullrich
				$dhcpdconf .= "}\n";
861
				$i++;
862
			}
863
		}
864 a25183c5 Scott Ullrich
865 6f9b8073 Ermal Luçi
		$dhcpdifs[] = get_real_interface($dhcpif);
866 3df2dbfd jim-p
		if ($newzone['domain-name'])
867 87019fc4 Andres Petralli
		{
868
			if ($need_ddns_updates)
869
			{
870
				$newzone['dns-servers'] = array($dhcpifconf['ddnsdomainprimary']);
871
			}
872 3df2dbfd jim-p
			$ddns_zones[] = $newzone;
873 87019fc4 Andres Petralli
		}
874 3df2dbfd jim-p
	}
875
876
	if ($need_ddns_updates) {
877
		$dhcpdconf .= "ddns-update-style interim;\n";
878 3cdef187 Andres Petralli
		$dhcpdconf .= "update-static-leases on;\n";
879 87019fc4 Andres Petralli
880
		$dhcpdconf .= dhcpdkey($dhcpifconf);
881
		$dhcpdconf .= dhcpdzones($ddns_zones, $dhcpifconf);
882 5b237745 Scott Ullrich
	}
883
884 abdd01f5 Ermal
	/* write dhcpd.conf */
885
	if (!@file_put_contents("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", $dhcpdconf)) {
886
		printf(gettext("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().%s"), "\n");
887
		unset($dhcpdconf);
888
		return 1;
889
	}
890 928d4416 Ermal
	unset($dhcpdconf);
891 2fb056d8 Seth Mos
892
	/* create an empty leases database */
893 abdd01f5 Ermal
	if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"))
894
		@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
895 2fb056d8 Seth Mos
896 b075c1e2 Chris Buechler
	/* make sure there isn't a stale dhcpd.pid file, which can make dhcpd fail to start.   */
897
	/* if we get here, dhcpd has been killed and is not started yet                        */ 
898
	unlink_if_exists("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
899
900 2fb056d8 Seth Mos
	/* fire up dhcpd in a chroot */
901 abdd01f5 Ermal
	if (count($dhcpdifs) > 0) {
902 2fb056d8 Seth Mos
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " .
903
			join(" ", $dhcpdifs));
904
	}
905
906 abdd01f5 Ermal
	if ($g['booting'])
907 2fb056d8 Seth Mos
		print "done.\n";
908
909
	return 0;
910
}
911
912 87019fc4 Andres Petralli
function dhcpdkey($dhcpifconf)
913
{
914
	$dhcpdconf = "";
915
	if ($dhcpifconf['ddnsdomainkeyname'] <> "" && $dhcpifconf['ddnsdomainkey'] <> "")
916
	{
917
		$dhcpdconf .= "key {$dhcpifconf['ddnsdomainkeyname']} {\n";
918
		$dhcpdconf .= "	algorithm hmac-md5;\n";
919
		$dhcpdconf .= "	secret {$dhcpifconf['ddnsdomainkey']};\n";
920
		$dhcpdconf .= "}\n";
921
	}
922
923
	return $dhcpdconf;
924
}
925
926
function dhcpdzones($ddns_zones, $dhcpifconf)
927
{
928
	$dhcpdconf = "";
929
930
	if (is_array($ddns_zones)) {
931
		$added_zones = array();
932
		foreach ($ddns_zones as $zone) {
933
			if (!is_array($zone) || empty($zone) || !is_array($zone['dns-servers']))
934
				continue;
935
			$primary = $zone['dns-servers'][0];
936
			$secondary = empty($zone['dns-servers'][1]) ? "" : $zone['dns-servers'][1];
937
938
			// Make sure we aren't using any invalid or IPv6 DNS servers.
939
			if (!is_ipaddrv4($primary)) {
940
				if (is_ipaddrv4($secondary)) {
941
					$primary = $secondary;
942
					$secondary = "";
943
				} else {
944
					continue;
945
				}
946
			}
947
948
			// We don't need to add zones multiple times.
949
			if ($zone['domain-name'] && !in_array($zone['domain-name'], $added_zones)) {
950
				$dhcpdconf .= "zone {$zone['domain-name']}. {\n";
951
				$dhcpdconf .= "	primary {$primary};\n";
952
				if (is_ipaddrv4($secondary))
953
					$dhcpdconf .= "	secondary {$secondary};\n";
954
				if($dhcpifconf['ddnsdomainkeyname'] <> "" && $dhcpifconf['ddnsdomainkey'] <> "")
955
                    $dhcpdconf .= "	key {$dhcpifconf['ddnsdomainkeyname']};\n";
956
				$dhcpdconf .= "}\n";
957
				$added_zones[] = $zone['domain-name'];
958
			}
959
			if ($zone['ptr-domain'] && !in_array($zone['ptr-domain'], $added_zones)) {
960
				$dhcpdconf .= "zone {$zone['ptr-domain']} {\n";
961
				$dhcpdconf .= "	primary {$primary};\n";
962
				if (is_ipaddrv4($secondary))
963
					$dhcpdconf .= "	secondary {$secondary};\n";
964
				if($dhcpifconf['ddnsdomainkeyname'] <> "" && $dhcpifconf['ddnsdomainkey'] <> "")
965
                    $dhcpdconf .= "	key {$dhcpifconf['ddnsdomainkeyname']};\n";
966
				$dhcpdconf .= "}\n";
967
				$added_zones[] = $zone['ptr-domain'];
968
			}
969
		}
970
	}
971
972
	return $dhcpdconf;
973
}
974
975 92977616 Ermal
function services_dhcpdv6_configure($blacklist = array()) {
976 2fb056d8 Seth Mos
	global $config, $g;
977 107e8acc Ovidiu Predescu
978
	if($g['services_dhcp_server_enable'] == false)
979 2fb056d8 Seth Mos
		return;
980
981
	if(isset($config['system']['developerspew'])) {
982
		$mt = microtime();
983
		echo "services_dhcpd_configure($if) being called $mt\n";
984
	}
985 107e8acc Ovidiu Predescu
986 2fb056d8 Seth Mos
	/* kill any running dhcpd */
987 abdd01f5 Ermal
	if (isvalidpid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid"))
988 bfb3e717 Seth Mos
		killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
989 abdd01f5 Ermal
	if (isvalidpid("{$g['varrun_path']}/dhcpleases6.pid"))
990 f7cd5647 smos
		killbypid("{$g['varrun_path']}/dhcpleases6.pid");
991 e9ab2ddb smos
992 2fb056d8 Seth Mos
	/* DHCP enabled on any interfaces? */
993 a6610d82 smos
	if (!is_dhcpv6_server_enabled())
994 2fb056d8 Seth Mos
		return 0;
995
996
	if ($g['booting']) {
997
		if ($g['platform'] != "pfSense") {
998
			/* restore the leases, if we have them */
999
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
1000
				$dhcprestore = "";
1001
				$dhcpreturn = "";
1002
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
1003
				$dhcprestore = implode(" ", $dhcprestore);
1004
				if($dhcpreturn <> 0) {
1005
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
1006
				}
1007
			}
1008
		}
1009
	}
1010
1011
	$syscfg = $config['system'];
1012
	if (!is_array($config['dhcpdv6']))
1013
		$config['dhcpdv6'] = array();
1014
	$dhcpdv6cfg = $config['dhcpdv6'];
1015
	$Iflist = get_configured_interface_list();
1016 e9ab2ddb smos
	$Iflist = array_merge($Iflist, get_configured_pppoe_server_interfaces());
1017
1018 107e8acc Ovidiu Predescu
1019 2fb056d8 Seth Mos
	if ($g['booting'])
1020
		echo "Starting DHCPv6 service...";
1021
	else
1022
		sleep(1);
1023
1024 a6610d82 smos
	/* we add a fake entry for interfaces that are set to track6 another WAN */
1025 abdd01f5 Ermal
	foreach ($Iflist as $ifname) {
1026 92977616 Ermal
		/* Do not put in the config an interface which is down */
1027
		if (isset($blacklist[$ifname]))
1028
			continue;
1029 abdd01f5 Ermal
		if (!empty($config['interfaces'][$ifname]['track6-interface'])) {
1030 06886ae3 Ermal
			$realif = get_real_interface($ifname, "inet6");
1031 c55a0f0c Ermal
			$ifcfgipv6 = get_interface_ipv6($ifname);
1032
			if(!is_ipaddrv6($ifcfgipv6))
1033
				continue;
1034
			$ifcfgipv6 = Net_IPv6::getNetmask($ifcfgipv6, 64);
1035 a6610d82 smos
			$trackifname = $config['interfaces'][$ifname]['track6-interface'];
1036
			$trackcfg = $config['interfaces'][$trackifname];
1037 319c2bfd smos
			$pdlen = calculate_ipv6_delegation_length($trackifname);
1038 a6610d82 smos
			$ifcfgipv6arr =explode(":", $ifcfgipv6);
1039
			$dhcpdv6cfg[$ifname] = array();
1040
			$dhcpdv6cfg[$ifname]['enable'] = true;
1041
			/* range */
1042
			$ifcfgipv6arr[7] = "1000";
1043 6fb66736 Ermal
			$dhcpdv6cfg[$ifname]['range'] = array();
1044 a6610d82 smos
			$dhcpdv6cfg[$ifname]['range']['from'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));
1045
			$ifcfgipv6arr[7] = "2000";
1046 91f026b0 ayvis
			$dhcpdv6cfg[$ifname]['range']['to'] = Net_IPv6::compress(implode(":", $ifcfgipv6arr));
1047 a6610d82 smos
			/* prefix length > 0? We can add dhcp6 prefix delegation server */
1048
			if($pdlen > 2) {
1049 c45b079d smos
				$pdlenmax = $pdlen;
1050 4aab9c6c smos
				$pdlenhalf = $pdlenmax -1;
1051
				$pdlenmin = (64 - ceil($pdlenhalf / 4));
1052 6fb66736 Ermal
				$dhcpdv6cfg[$ifname]['prefixrange'] = array();
1053 4aab9c6c smos
				$dhcpdv6cfg[$ifname]['prefixrange']['prefixlength'] = $pdlenmin;
1054
1055
				/* set the delegation start to half the current address block */
1056 c45b079d smos
				$range = Net_IPv6::parseAddress($ifcfgipv6, (64 - $pdlenmax));
1057 4aab9c6c smos
				$range['start'] = Net_IPv6::getNetmask($range['end'], (64 - $pdlenhalf));
1058
1059
				/* set the end range to a multiple of the prefix delegation size, required by dhcpd */
1060 c45b079d smos
				$range = Net_IPv6::parseAddress($range['end'], (64 - $pdlenhalf));
1061 4aab9c6c smos
				$range['end'] = Net_IPv6::getNetmask($range['end'], (64 - round($pdlen / 2)));
1062
1063 a6610d82 smos
				$dhcpdv6cfg[$ifname]['prefixrange']['from'] = Net_IPv6::compress($range['start']);
1064
				$dhcpdv6cfg[$ifname]['prefixrange']['to'] = Net_IPv6::compress($range['end']);
1065 70da4172 Jean Cyr
				$dhcpdv6cfg[$ifname]['dns6ip'] = get_interface_ipv6($ifname);
1066 a6610d82 smos
			}
1067
		}
1068
	}
1069
1070 2fb056d8 Seth Mos
	$custoptionsv6 = "";
1071 107e8acc Ovidiu Predescu
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
1072 2fb056d8 Seth Mos
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
1073
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
1074
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
1075
			}
1076
		}
1077
	}
1078
1079 bd942860 Renato Botelho
	if(isset($dhcpv6ifconf['netboot']) && !empty($dhcpv6ifconf['bootfile_url']))
1080
		$custoptionsv6 .= "option dhcp6.bootfile-url code 59 = string;\n";
1081
1082 2fb056d8 Seth Mos
	$dhcpdv6conf = <<<EOD
1083 107e8acc Ovidiu Predescu
1084 2fb056d8 Seth Mos
option domain-name "{$syscfg['domain']}";
1085
option ldap-server code 95 = text;
1086
option domain-search-list code 119 = text;
1087 547f1e65 Renato Botelho
{$custoptionsv6}
1088 2fb056d8 Seth Mos
default-lease-time 7200;
1089
max-lease-time 86400;
1090
log-facility local7;
1091
one-lease-per-client true;
1092
deny duplicates;
1093
ping-check true;
1094 87019fc4 Andres Petralli
update-conflict-detection false;
1095 2fb056d8 Seth Mos
1096
EOD;
1097
1098
	if(!isset($dhcpv6ifconf['disableauthoritative']))
1099
		$dhcpdv6conf .= "authoritative;\n";
1100
1101 107e8acc Ovidiu Predescu
	if(isset($dhcpv6ifconf['alwaysbroadcast']))
1102 2fb056d8 Seth Mos
		$dhcpdv6conf .= "always-broadcast on\n";
1103
1104
	$dhcpdv6ifs = array();
1105
1106 693833cb Seth Mos
	$dhcpv6num = 0;
1107 87019fc4 Andres Petralli
	$nsupdate = false;
1108
1109 693833cb Seth Mos
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
1110
1111 87019fc4 Andres Petralli
		$ddns_zones = array();
1112
1113 693833cb Seth Mos
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
1114
1115
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
1116
			continue;
1117
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
1118
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
1119 d57293a4 Seth Mos
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
1120 693833cb Seth Mos
1121 1944af41 Ermal
		if ($is_olsr_enabled == true) {
1122 693833cb Seth Mos
			if($dhcpv6ifconf['netmask'])
1123 bfb3e717 Seth Mos
				$subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']);
1124 1944af41 Ermal
		}
1125 693833cb Seth Mos
1126
		$dnscfgv6 = "";
1127
1128
		if ($dhcpv6ifconf['domain']) {
1129 3c009080 Seth Mos
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
1130 693833cb Seth Mos
		}
1131 107e8acc Ovidiu Predescu
1132 87019fc4 Andres Petralli
    	if ($dhcpv6ifconf['domainsearchlist'] <> "") {
1133 a3de8b9e Pierre POMES
			$dnscfgv6 .= "	option domain-search \"" . join("\",\"", preg_split("/[ ;]+/", $dhcpv6ifconf['domainsearchlist'])) . "\";\n";
1134 87019fc4 Andres Petralli
    	}
1135 693833cb Seth Mos
1136
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
1137
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
1138 3c009080 Seth Mos
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
1139 693833cb Seth Mos
			}
1140 3c009080 Seth Mos
			$dnscfgv6 .= "	ddns-update-style interim;\n";
1141 87019fc4 Andres Petralli
			$nsupdate = true;
1142 693833cb Seth Mos
		}
1143
1144
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
1145
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
1146 e9ab2ddb smos
		} else if ((isset($config['dnsmasq']['enable'])) && (is_ipaddrv6($ifcfgipv6))) {
1147 693833cb Seth Mos
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
1148
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1149 2521266a Seth Mos
			$dns_arrv6 = array();
1150
			foreach($syscfg['dnsserver'] as $dnsserver) {
1151 1944af41 Ermal
				if (is_ipaddrv6($dnsserver)) {
1152 2521266a Seth Mos
					$dns_arrv6[] = $dnsserver;
1153
				}
1154
			}
1155
			if(!empty($dns_arrv6))
1156 2816c5a1 Seth Mos
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
1157 693833cb Seth Mos
		}
1158
1159 87019fc4 Andres Petralli
		if ($dhcpv6ifconf['domain']) {
1160
			$newzone = array();
1161
			$newzone['domain-name'] = $dhcpv6ifconf['domain']; 
1162
			$newzone['dns-servers'][] = $dhcpv6ifconf['ddnsdomainprimary'];
1163
			$ddns_zones[] = $newzone;
1164
		}
1165
1166 1944af41 Ermal
		if (is_ipaddrv6($ifcfgipv6)) {
1167
			$dhcpdv6conf .= "subnet6 {$subnetv6}/{$ifcfgsnv6}";
1168 e9ab2ddb smos
		} else {
1169 88cc00db Ermal
			$subnet6 = gen_subnetv6($dhcpv6ifconf['range']['from'], "64");
1170 1944af41 Ermal
			$dhcpdv6conf .= "subnet6 {$subnet6}/64";
1171 abdd01f5 Ermal
		}
1172 1944af41 Ermal
		$dhcpdv6conf .= " {\n";
1173 693833cb Seth Mos
1174
		$dhcpdv6conf .= <<<EOD
1175
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
1176
$dnscfgv6
1177
1178
EOD;
1179 bfb3e717 Seth Mos
1180 1944af41 Ermal
		if (is_ipaddrv6($dhcpv6ifconf['prefixrange']['from']) && is_ipaddrv6($dhcpv6ifconf['prefixrange']['to'])) {
1181 3f9492a7 Seth Mos
			$dhcpdv6conf .= "	prefix6 {$dhcpv6ifconf['prefixrange']['from']} {$dhcpv6ifconf['prefixrange']['to']}/{$dhcpv6ifconf['prefixrange']['prefixlength']};\n";
1182 bfb3e717 Seth Mos
		}
1183 70da4172 Jean Cyr
		if (is_ipaddrv6($dhcpv6ifconf['dns6ip'])) {
1184
			$dhcpdv6conf .= "       option dhcp6.name-servers {$dhcpv6ifconf['dns6ip']};\n";
1185
		}
1186 693833cb Seth Mos
    		// default-lease-time
1187
		if ($dhcpv6ifconf['defaultleasetime'])
1188
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
1189
1190
		// max-lease-time
1191
		if ($dhcpv6ifconf['maxleasetime'])
1192
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
1193
1194
		// ntp-servers
1195 4096fe5d smos
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) {
1196
			$ntpservers = array();
1197
			foreach($dhcpv6ifconf['ntpserver'] as $ntpserver) {
1198
				if(is_ipaddrv6($ntpserver))
1199
					$ntpservers[] = $ntpserver;
1200
			}
1201
			if(count($ntpservers) > 0 )
1202
				$dhcpdv6conf .= "       option dhcp6.sntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
1203
		}
1204 693833cb Seth Mos
		// tftp-server-name
1205 7d504365 smos
		/* Needs ISC DHCPD support
1206
		 if ($dhcpv6ifconf['tftp'] <> "")
1207 693833cb Seth Mos
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
1208 7d504365 smos
		*/
1209 693833cb Seth Mos
1210
		// Handle option, number rowhelper values
1211
		$dhcpdv6conf .= "\n";
1212 1944af41 Ermal
		if ($dhcpv6ifconf['numberoptions']['item']) {
1213 693833cb Seth Mos
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
1214
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
1215
			}
1216
		}
1217
1218
		// ldap-server
1219
		if ($dhcpv6ifconf['ldap'] <> "")
1220
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
1221
1222
		// net boot information
1223
		if(isset($dhcpv6ifconf['netboot'])) {
1224 bd942860 Renato Botelho
			if (!empty($dhcpv6ifconf['bootfile_url'])) {
1225
				$dhcpdv6conf .= "	option dhcp6.bootfile-url \"{$dhcpv6ifconf['bootfile_url']}\";\n";
1226 abdd01f5 Ermal
			}
1227
		}
1228 107e8acc Ovidiu Predescu
1229 1c903aa4 Ermal
		$dhcpdv6conf .= "}\n";
1230 693833cb Seth Mos
1231
		/* add static mappings */
1232 2fb056d8 Seth Mos
		/* Needs to use DUID */
1233 693833cb Seth Mos
		if (is_array($dhcpv6ifconf['staticmap'])) {
1234
			$i = 0;
1235
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
1236
				$dhcpdv6conf .= <<<EOD
1237
host s_{$dhcpv6if}_{$i} {
1238 2fb056d8 Seth Mos
	host-identifier option dhcp6.client-id {$sm['duid']};
1239 693833cb Seth Mos
1240
EOD;
1241 2fb056d8 Seth Mos
				if ($sm['ipaddrv6'])
1242
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddrv6']};\n";
1243 693833cb Seth Mos
1244
				if ($sm['hostname']) {
1245
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
1246
					$dhhostname = str_replace(".", "_", $dhhostname);
1247
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
1248
				}
1249 a2578c27 Anthony Wrather
				if ($sm['filename'])
1250
					$dhcpdv6conf .= "	filename \"{$sm['filename']}\";\n";
1251
1252
				if ($sm['rootpath'])
1253
					$dhcpdv6conf .= "	option root-path \"{$sm['rootpath']}\";\n";
1254 693833cb Seth Mos
1255
				$dhcpdv6conf .= "}\n";
1256
				$i++;
1257
			}
1258
		}
1259 107e8acc Ovidiu Predescu
1260 87019fc4 Andres Petralli
		if ($dhcpv6ifconf['domain'])
1261
		{
1262
			$dhcpdv6conf .= dhcpdkey($dhcpv6ifconf);
1263
			$dhcpdv6conf .= dhcpdzones($ddns_zones, $dhcpv6ifconf);
1264
		}
1265
1266 1944af41 Ermal
		if ($config['dhcpdv6'][$dhcpv6if]['ramode'] <> "unmanaged") {
1267 e9ab2ddb smos
			if(preg_match("/poes/si", $dhcpv6if)) {
1268
				/* magic here */
1269
				$dhcpdv6ifs = array_merge($dhcpdv6ifs, get_pppoes_child_interfaces($dhcpv6if));
1270
			} else {
1271 1944af41 Ermal
				$realif = get_real_interface($dhcpv6if, "inet6");
1272 029b377a Ermal
				if (stristr("$realif", "bridge")) {
1273
					$mac = get_interface_mac($realif);
1274
					$v6address = generate_ipv6_from_mac($mac);
1275
					/* Create link local address for bridges */
1276 e9ab2ddb smos
					mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}");
1277
				}
1278 029b377a Ermal
				$realif = escapeshellcmd($realif);
1279
				$dhcpdv6ifs[] = $realif;
1280 656f1763 Seth Mos
			}
1281 de140730 Seth Mos
		}
1282 693833cb Seth Mos
	}
1283
1284 87019fc4 Andres Petralli
	if ($nsupdate)
1285
	{
1286
		$dhcpdv6conf .= "ddns-update-style interim;\n";
1287
	}
1288
	else
1289
	{
1290
		$dhcpdv6conf .= "ddns-update-style none;\n";
1291
	}
1292
1293 abdd01f5 Ermal
	/* write dhcpdv6.conf */
1294
	if (!@file_put_contents("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", $dhcpdv6conf)) {
1295 1c903aa4 Ermal
		log_error("Error: cannot open {$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf in services_dhcpdv6_configure().\n");
1296 abdd01f5 Ermal
		if ($g['booting'])
1297 1c903aa4 Ermal
			printf("Error: cannot open {$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf in services_dhcpdv6_configure().\n");
1298 abdd01f5 Ermal
		unset($dhcpdv6conf);
1299
		return 1;
1300
	}
1301 928d4416 Ermal
	unset($dhcpdv6conf);
1302
1303 693833cb Seth Mos
	/* create an empty leases v6 database */
1304 abdd01f5 Ermal
	if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases"))
1305
		@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1306 107e8acc Ovidiu Predescu
1307 b075c1e2 Chris Buechler
        /* make sure there isn't a stale dhcpdv6.pid file, which may make dhcpdv6 fail to start.  */
1308
        /* if we get here, dhcpdv6 has been killed and is not started yet                         */
1309
        unlink_if_exists("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
1310
1311 68a0e4fc Scott Ullrich
	/* fire up dhcpd in a chroot */
1312 abdd01f5 Ermal
	if (count($dhcpdv6ifs) > 0) {
1313 2fb056d8 Seth Mos
		mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf -pf {$g['varrun_path']}/dhcpdv6.pid " .
1314 2a1bd027 Seth Mos
			join(" ", $dhcpdv6ifs));
1315 d48ed103 smos
		mwexec("/usr/local/sbin/dhcpleases6 -c \"/usr/local/bin/php -f /usr/local/sbin/prefixes.php|/bin/sh\" -l {$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
1316 2a1bd027 Seth Mos
	}
1317 abdd01f5 Ermal
	if ($g['booting'])
1318 f1a44a3a Carlos Eduardo Ramos
		print gettext("done.") . "\n";
1319 a25183c5 Scott Ullrich
1320 5b237745 Scott Ullrich
	return 0;
1321
}
1322
1323 41997fbb Ermal Luci
function services_igmpproxy_configure() {
1324
        global $config, $g;
1325
1326
        /* kill any running igmpproxy */
1327
        killbyname("igmpproxy");
1328
1329 f86f6fb2 bcyrill
	if (!is_array($config['igmpproxy']['igmpentry']) || (count($config['igmpproxy']['igmpentry']) == 0))
1330 41997fbb Ermal Luci
		return 1;
1331
1332 f206afb5 Ermal
        $iflist = get_configured_interface_list();
1333
1334 41997fbb Ermal Luci
        $igmpconf = <<<EOD
1335
1336
##------------------------------------------------------
1337
## Enable Quickleave mode (Sends Leave instantly)
1338
##------------------------------------------------------
1339
quickleave
1340
1341
EOD;
1342
1343
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
1344
                unset($iflist[$igmpcf['ifname']]);
1345
                $realif = get_real_interface($igmpcf['ifname']);
1346
                if (empty($igmpcf['threshold']))
1347
                        $threshld = 1;
1348
                else
1349
                        $threshld = $igmpcf['threshold'];
1350
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
1351
1352
                if ($igmpcf['address'] <> "") {
1353
                        $item = explode(" ", $igmpcf['address']);
1354
                        foreach($item as $iww)
1355
                                $igmpconf .= "altnet {$iww}\n";
1356
                }
1357
                $igmpconf .= "\n";
1358
        }
1359
        foreach ($iflist as $ifn) {
1360
                $realif = get_real_interface($ifn);
1361
                $igmpconf .= "phyint {$realif} disabled\n";
1362
        }
1363 3bae60be Ermal
	$igmpconf .= "\n";
1364 41997fbb Ermal Luci
1365
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
1366
        if (!$igmpfl) {
1367 f1a44a3a Carlos Eduardo Ramos
                log_error(gettext("Could not write Igmpproxy configuration file!"));
1368 41997fbb Ermal Luci
                return;
1369
        }
1370
        fwrite($igmpfl, $igmpconf);
1371
        fclose($igmpfl);
1372 928d4416 Ermal
	unset($igmpconf);
1373 41997fbb Ermal Luci
1374 d629f1ca Renato Botelho
	/* NOTE: -d4 means everything LOG_WARNING and smaller */
1375
        mwexec("/usr/local/sbin/igmpproxy -d4 -c {$g['tmp_path']}/igmpproxy.conf");
1376 d372a32d Chris Buechler
        log_error(gettext("Started IGMP proxy service."));
1377 41997fbb Ermal Luci
1378
        return 0;
1379
}
1380
1381 5b237745 Scott Ullrich
function services_dhcrelay_configure() {
1382 f19d3b7a Scott Ullrich
	global $config, $g;
1383 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
1384
		return;
1385 58c7450e Scott Ullrich
	if(isset($config['system']['developerspew'])) {
1386 acd910bf Scott Ullrich
		$mt = microtime();
1387 f19d3b7a Scott Ullrich
		echo "services_dhcrelay_configure() being called $mt\n";
1388 acd910bf Scott Ullrich
	}
1389 a25183c5 Scott Ullrich
1390 5b237745 Scott Ullrich
	/* kill any running dhcrelay */
1391
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
1392 a25183c5 Scott Ullrich
1393 2f06cc3f Ermal
	$dhcrelaycfg =& $config['dhcrelay'];
1394 a25183c5 Scott Ullrich
1395 5b237745 Scott Ullrich
	/* DHCPRelay enabled on any interfaces? */
1396 2f06cc3f Ermal
	if (!isset($dhcrelaycfg['enable']))
1397 5b237745 Scott Ullrich
		return 0;
1398 a25183c5 Scott Ullrich
1399 5b237745 Scott Ullrich
	if ($g['booting'])
1400 f1a44a3a Carlos Eduardo Ramos
		echo gettext("Starting DHCP relay service...");
1401 5b237745 Scott Ullrich
	else
1402
		sleep(1);
1403 a25183c5 Scott Ullrich
1404 2f06cc3f Ermal
	$iflist = get_configured_interface_list();
1405 a25183c5 Scott Ullrich
1406 2f06cc3f Ermal
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1407
	foreach ($dhcifaces as $dhcrelayif) {
1408
		if (!isset($iflist[$dhcrelayif]) ||
1409
			link_interface_to_bridge($dhcrelayif))
1410 5b237745 Scott Ullrich
			continue;
1411 a25183c5 Scott Ullrich
1412 2f06cc3f Ermal
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
1413
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1414 5b237745 Scott Ullrich
	}
1415
1416 107e8acc Ovidiu Predescu
	/*
1417 2f06cc3f Ermal
	 * In order for the relay to work, it needs to be active
1418
	 * on the interface in which the destination server sits.
1419
	 */
1420
	$srvips = explode(",", $dhcrelaycfg['server']);
1421
	foreach ($srvips as $srcidx => $srvip) {
1422
		unset($destif);
1423
		foreach ($iflist as $ifname) {
1424
			$subnet = get_interface_ip($ifname);
1425
			if (!is_ipaddr($subnet))
1426
				continue;
1427
			$subnet .=  "/" . get_interface_subnet($ifname);
1428
			if (ip_in_subnet($srvip, $subnet)) {
1429
				$destif = get_real_interface($ifname);
1430
				break;
1431
			}
1432 6f9b154b Ermal
		}
1433 2f06cc3f Ermal
		if (!isset($destif)) {
1434 f898c1a9 jim-p
			foreach (get_staticroutes() as $rtent) {
1435
				if (ip_in_subnet($srvip, $rtent['network'])) {
1436
					$a_gateways = return_gateways_array(true);
1437
					$destif = $a_gateways[$rtent['gateway']]['interface'];
1438
					break;
1439 6f9b154b Ermal
				}
1440
			}
1441
		}
1442 a25183c5 Scott Ullrich
1443 2f06cc3f Ermal
		if (!isset($destif)) {
1444
			/* Create a array from the existing route table */
1445
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
1446
        		array_shift($route_str);
1447
        		array_shift($route_str);
1448
        		array_shift($route_str);
1449
        		array_shift($route_str);
1450
        		$route_arr = array();
1451
        		foreach($route_str as $routeline) {
1452 f3f7cef4 jim-p
				$items = preg_split("/[ ]+/i", $routeline);
1453
				if (is_subnetv4($items[0])) {
1454
					$subnet = $items[0];
1455
				} elseif (is_ipaddrv4($items[0])) {
1456
					$subnet = "{$items[0]}/32";
1457
				} else {
1458
					// Not a subnet or IP address, skip to the next line.
1459
					continue;
1460
				}
1461
				if (ip_in_subnet($srvip, $subnet)) {
1462 5e80046a Ermal
					$destif = trim($items[6]);
1463 c935eb77 Ermal
					break;
1464 2f06cc3f Ermal
				}
1465 f3f7cef4 jim-p
			}
1466 2f06cc3f Ermal
		}
1467 107e8acc Ovidiu Predescu
1468 2f06cc3f Ermal
		if (!isset($destif)) {
1469
			if (is_array($config['gateways']['gateway_item'])) {
1470
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1471
					if (isset($gateway['defaultgw'])) {
1472 c30639e4 Phil Davis
						$destif = get_real_interface($gateway['interface']);
1473 2f06cc3f Ermal
						break;
1474 107e8acc Ovidiu Predescu
					}
1475 2f06cc3f Ermal
				}
1476
			} else
1477
				$destif = get_real_interface("wan");
1478
		}
1479 a25183c5 Scott Ullrich
1480 24997966 Ermal
		if (!empty($destif))
1481
			$dhcrelayifs[] = $destif;
1482 2f06cc3f Ermal
	}
1483 5b237745 Scott Ullrich
	$dhcrelayifs = array_unique($dhcrelayifs);
1484
1485
	/* fire up dhcrelay */
1486 24997966 Ermal
	if (empty($dhcrelayifs)) {
1487 5a171fb7 Warren Baker
		log_error("No suitable interface found for running dhcrelay!");
1488 24997966 Ermal
		return; /* XXX */
1489
	}
1490
1491
	$cmd = "/usr/local/sbin/dhcrelay -i " .  implode(" -i ", $dhcrelayifs);
1492 5b237745 Scott Ullrich
1493 a25183c5 Scott Ullrich
	if (isset($dhcrelaycfg['agentoption']))
1494 5b237745 Scott Ullrich
		$cmd .=  " -a -m replace";
1495
1496 2f06cc3f Ermal
	$cmd .= " " . implode(" ", $srvips);
1497 5b237745 Scott Ullrich
	mwexec($cmd);
1498 928d4416 Ermal
	unset($cmd);
1499 a25183c5 Scott Ullrich
1500 5b237745 Scott Ullrich
	return 0;
1501
}
1502
1503 b7a15cf8 Seth Mos
function services_dhcrelay6_configure() {
1504
	global $config, $g;
1505
	if ($g['platform'] == 'jail')
1506
		return;
1507
	if(isset($config['system']['developerspew'])) {
1508
		$mt = microtime();
1509 874f099a Phil Davis
		echo "services_dhcrelay6_configure() being called $mt\n";
1510 b7a15cf8 Seth Mos
	}
1511
1512
	/* kill any running dhcrelay */
1513
	killbypid("{$g['varrun_path']}/dhcrelay6.pid");
1514
1515
	$dhcrelaycfg =& $config['dhcrelay6'];
1516
1517
	/* DHCPv6 Relay enabled on any interfaces? */
1518
	if (!isset($dhcrelaycfg['enable']))
1519
		return 0;
1520
1521
	if ($g['booting'])
1522
		echo gettext("Starting DHCPv6 relay service...");
1523
	else
1524
		sleep(1);
1525
1526
	$iflist = get_configured_interface_list();
1527
1528
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
1529
	foreach ($dhcifaces as $dhcrelayif) {
1530
		if (!isset($iflist[$dhcrelayif]) ||
1531
			link_interface_to_bridge($dhcrelayif))
1532
			continue;
1533
1534
		if (is_ipaddrv6(get_interface_ipv6($dhcrelayif)))
1535
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
1536
	}
1537 69dd7088 Michael Tharp
	$dhcrelayifs = array_unique($dhcrelayifs);
1538 b7a15cf8 Seth Mos
1539 107e8acc Ovidiu Predescu
	/*
1540 b7a15cf8 Seth Mos
	 * In order for the relay to work, it needs to be active
1541
	 * on the interface in which the destination server sits.
1542
	 */
1543
	$srvips = explode(",", $dhcrelaycfg['server']);
1544 69dd7088 Michael Tharp
        $srvifaces = array();
1545 b7a15cf8 Seth Mos
	foreach ($srvips as $srcidx => $srvip) {
1546
		unset($destif);
1547
		foreach ($iflist as $ifname) {
1548
			$subnet = get_interface_ipv6($ifname);
1549
			if (!is_ipaddrv6($subnet))
1550
				continue;
1551
			$subnet .=  "/" . get_interface_subnetv6($ifname);
1552
			if (ip_in_subnet($srvip, $subnet)) {
1553
				$destif = get_real_interface($ifname);
1554
				break;
1555
			}
1556
		}
1557
		if (!isset($destif)) {
1558
			if (is_array($config['staticroutes']['route'])) {
1559
				foreach ($config['staticroutes']['route'] as $rtent) {
1560
					if (ip_in_subnet($srvip, $rtent['network'])) {
1561
						$a_gateways = return_gateways_array(true);
1562
						$destif = $a_gateways[$rtent['gateway']]['interface'];
1563
						break;
1564
					}
1565
				}
1566
			}
1567
		}
1568
1569
		if (!isset($destif)) {
1570
			/* Create a array from the existing route table */
1571
        		exec("/usr/bin/netstat -rnWf inet6", $route_str);
1572
        		array_shift($route_str);
1573
        		array_shift($route_str);
1574
        		array_shift($route_str);
1575
        		array_shift($route_str);
1576
        		$route_arr = array();
1577
        		foreach($route_str as $routeline) {
1578
                		$items = preg_split("/[ ]+/i", $routeline);
1579
				if (ip_in_subnet($srvip, $items[0])) {
1580
					$destif = trim($items[6]);
1581
					break;
1582
				}
1583
        		}
1584
		}
1585 107e8acc Ovidiu Predescu
1586 b7a15cf8 Seth Mos
		if (!isset($destif)) {
1587
			if (is_array($config['gateways']['gateway_item'])) {
1588
				foreach ($config['gateways']['gateway_item'] as $gateway) {
1589
					if (isset($gateway['defaultgw'])) {
1590 20623f57 Renato Botelho
						$destif = $gateway['interface'];
1591 b7a15cf8 Seth Mos
						break;
1592 107e8acc Ovidiu Predescu
					}
1593 b7a15cf8 Seth Mos
				}
1594
			} else
1595
				$destif = get_real_interface("wan");
1596
		}
1597
1598 69dd7088 Michael Tharp
		if (!empty($destif)) {
1599
			$srvifaces[] = "{$srvip}%{$destif}";
1600
		}
1601 b7a15cf8 Seth Mos
	}
1602
1603
	/* fire up dhcrelay */
1604 69dd7088 Michael Tharp
	if (empty($dhcrelayifs) || empty($srvifaces) ) {
1605 b7a15cf8 Seth Mos
		log_error("No suitable interface found for running dhcrelay -6!");
1606
		return; /* XXX */
1607
	}
1608
1609 54a9d71d Phil Davis
	$cmd = "/usr/local/sbin/dhcrelay -6 -pf \"{$g['varrun_path']}/dhcrelay6.pid\"";
1610 69dd7088 Michael Tharp
	foreach ($dhcrelayifs as $dhcrelayif) {
1611
		$cmd .= " -l {$dhcrelayif}";
1612
	}
1613
	foreach ($srvifaces as $srviface) {
1614
		$cmd .= " -u \"{$srviface}\"";
1615
	}
1616 b7a15cf8 Seth Mos
	mwexec($cmd);
1617 928d4416 Ermal
	unset($cmd);
1618 b7a15cf8 Seth Mos
1619
	return 0;
1620
}
1621
1622 181d7c95 Ermal Luçi
function services_dyndns_configure_client($conf) {
1623
1624 d2946062 Ermal
	if (!isset($conf['enable']))
1625 65996399 Ermal
		return;
1626 d2946062 Ermal
1627 181d7c95 Ermal Luçi
	/* load up the dyndns.class */
1628
	require_once("dyndns.class");
1629
1630
	$dns = new updatedns($dnsService = $conf['type'],
1631
		$dnsHost = $conf['host'],
1632
		$dnsUser = $conf['username'],
1633
		$dnsPass = $conf['password'],
1634
		$dnsWilcard = $conf['wildcard'],
1635 107e8acc Ovidiu Predescu
		$dnsMX = $conf['mx'],
1636 f3b2b2a4 Yehuda Katz
		$dnsIf = "{$conf['interface']}",
1637
		$dnsBackMX = NULL,
1638
		$dnsServer = NULL,
1639
		$dnsPort = NULL,
1640 37f3e704 Matt Corallo
		$dnsUpdateURL = "{$conf['updateurl']}",
1641 cd132e86 Edson Brandi
		$forceUpdate = $conf['force'],
1642 1e503870 Phil Davis
		$dnsZoneID=$conf['zoneid'],
1643
		$dnsTTL=$conf['ttl'],
1644 37f3e704 Matt Corallo
		$dnsResultMatch = "{$conf['resultmatch']}",
1645
		$dnsRequestIf = "{$conf['requestif']}",
1646 1e503870 Phil Davis
		$dnsID = "{$conf['id']}",
1647 aa79f351 Sebastian Chrostek
		$dnsVerboseLog = $conf['verboselog'],
1648
		$curlIpresolveV4 = $conf['curl_ipresolve_v4'],
1649
		$curlSslVerifypeer = $conf['curl_ssl_verifypeer']);
1650 181d7c95 Ermal Luçi
}
1651
1652 0be93267 Ermal Lu?i
function services_dyndns_configure($int = "") {
1653 f19d3b7a Scott Ullrich
	global $config, $g;
1654 59a63553 Scott Ullrich
	if(isset($config['system']['developerspew'])) {
1655
		$mt = microtime();
1656
		echo "services_dyndns_configure() being called $mt\n";
1657
	}
1658
1659 67ee1ec5 Ermal Luçi
	$dyndnscfg = $config['dyndnses']['dyndns'];
1660 017817c2 smos
	$gwgroups = return_gateway_groups_array();
1661 67ee1ec5 Ermal Luçi
	if (is_array($dyndnscfg)) {
1662 107e8acc Ovidiu Predescu
		if ($g['booting'])
1663 f1a44a3a Carlos Eduardo Ramos
			echo gettext("Starting DynDNS clients...");
1664 181d7c95 Ermal Luçi
1665 67ee1ec5 Ermal Luçi
		foreach ($dyndnscfg as $dyndns) {
1666 786ff5eb phildd
			if ((empty($int)) || ($int == $dyndns['interface']) || (is_array($gwgroups[$dyndns['interface']]))) {
1667 1e503870 Phil Davis
				$dyndns['verboselog'] = isset($dyndns['verboselog']);
1668 d9bdc020 Sebastian Chrostek
				$dyndns['curl_ipresolve_v4'] = isset($dyndns['curl_ipresolve_v4']);
1669
				$dyndns['curl_ssl_verifypeer'] = isset($dyndns['curl_ssl_verifypeer']);
1670 768eb89c smos
				services_dyndns_configure_client($dyndns);
1671
				sleep(1);
1672
			}
1673 67ee1ec5 Ermal Luçi
		}
1674 59a63553 Scott Ullrich
1675
		if ($g['booting'])
1676 f1a44a3a Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1677 59a63553 Scott Ullrich
	}
1678
1679
	return 0;
1680
}
1681
1682 0e3aeb6b Phil Davis
function dyndnsCheckIP($int) {
1683 873e4b28 phildd
	global $config;
1684 0e3aeb6b Phil Davis
	$ip_address = get_interface_ip($int);
1685
	if (is_private_ip($ip_address)) {
1686 873e4b28 phildd
		$gateways_status = return_gateways_status(true);
1687
		// If the gateway for this interface is down, then the external check cannot work.
1688
		// Avoid the long wait for the external check to timeout.
1689
		if (stristr($gateways_status[$config['interfaces'][$int]['gateway']]['status'],"down"))
1690
			return "down";
1691 5244c510 Florian Asche
		$hosttocheck = "http://checkip.dyndns.org";
1692
		$ip_ch = curl_init($hosttocheck);
1693 0e3aeb6b Phil Davis
		curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1);
1694
		curl_setopt($ip_ch, CURLOPT_SSL_VERIFYPEER, FALSE);
1695
		curl_setopt($ip_ch, CURLOPT_INTERFACE, $ip_address);
1696 181386d6 Florian Asche
		curl_setopt($ip_ch, CURLOPT_CONNECTTIMEOUT, '30');
1697
		curl_setopt($ip_ch, CURLOPT_TIMEOUT, 120);
1698 3c6f29c0 Florian Asche
		curl_setopt($ip_ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1699 0e3aeb6b Phil Davis
		$ip_result_page = curl_exec($ip_ch);
1700
		curl_close($ip_ch);
1701
		$ip_result_decoded = urldecode($ip_result_page);
1702
		preg_match('=Current IP Address: (.*)</body>=siU', $ip_result_decoded, $matches);
1703
		$ip_address = trim($matches[1]);
1704
	}
1705
	return $ip_address;
1706
}
1707
1708 5b237745 Scott Ullrich
function services_dnsmasq_configure() {
1709 f19d3b7a Scott Ullrich
	global $config, $g;
1710 6a01ea44 Bill Marquette
	$return = 0;
1711 107e8acc Ovidiu Predescu
1712 683992fc stilez
	// hard coded args: will be removed to avoid duplication if specified in custom_options
1713
	$standard_args = array(
1714
		"dns-forward-max" => "--dns-forward-max=5000",
1715
		"cache-size" => "--cache-size=10000",
1716
		"local-ttl" => "--local-ttl=1"
1717
	);
1718
1719
1720 58c7450e Scott Ullrich
	if(isset($config['system']['developerspew'])) {
1721 acd910bf Scott Ullrich
		$mt = microtime();
1722 f19d3b7a Scott Ullrich
		echo "services_dnsmasq_configure() being called $mt\n";
1723 acd910bf Scott Ullrich
	}
1724
1725 5b237745 Scott Ullrich
	/* kill any running dnsmasq */
1726 d224df18 Ermal
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
1727
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1728 5b237745 Scott Ullrich
1729
	if (isset($config['dnsmasq']['enable'])) {
1730 a25183c5 Scott Ullrich
1731 5b237745 Scott Ullrich
		if ($g['booting'])
1732 f1a44a3a Carlos Eduardo Ramos
			echo gettext("Starting DNS forwarder...");
1733 5b237745 Scott Ullrich
		else
1734
			sleep(1);
1735
1736
		$args = "";
1737 a25183c5 Scott Ullrich
1738 0261381a Ermal
		if (isset($config['dnsmasq']['regdhcp'])) {
1739
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1740
		}
1741 107e8acc Ovidiu Predescu
1742 e6c49e3d jim-p
		/* Setup listen port, if non-default */
1743
		if (is_port($config['dnsmasq']['port']))
1744
			$args .= " --port={$config['dnsmasq']['port']} ";
1745
1746 b4323f39 jim-p
		$listen_addresses = "";
1747
		if(isset($config['dnsmasq']['interface'])) {
1748
			$interfaces = explode(",", $config['dnsmasq']['interface']);
1749
			foreach ($interfaces as $interface) {
1750 55909a9a Ermal
				if (is_ipaddrv4($interface)) {
1751 b4323f39 jim-p
					$listen_addresses .= " --listen-address={$interface} ";
1752 55909a9a Ermal
				} else if (is_ipaddrv6($interface)) {
1753
					/*
1754
					 * XXX: Since dnsmasq does not support link-local address
1755
					 * with scope specified. These checks are being done.
1756
					 */
1757
					if (is_linklocal($interface) && strstr($interface, "%")) {
1758
						$tmpaddrll6 = explode("%", $interface);
1759
						$listen_addresses .= " --listen-address={$tmpaddrll6[0]} ";
1760
					} else 
1761
						$listen_addresses .= " --listen-address={$interface} ";
1762 b4323f39 jim-p
				} else {
1763
					$if = get_real_interface($interface);
1764
					if (does_interface_exist($if)) {
1765
						$laddr = find_interface_ip($if);
1766
						if (is_ipaddrv4($laddr))
1767
							$listen_addresses .= " --listen-address={$laddr} ";
1768
						$laddr6 = find_interface_ipv6($if);
1769 b77d19c7 Ermal
						if (is_ipaddrv6($laddr6) && !isset($config['dnsmasq']['strictbind'])) {
1770
							/*
1771
							 * XXX: Since dnsmasq does not support link-local address
1772
							 * with scope specified. These checks are being done.
1773
							 */
1774
							if (is_linklocal($laddr6) && strstr($laddr6, "%")) {
1775
								$tmpaddrll6 = explode("%", $laddr6);
1776
								$listen_addresses .= " --listen-address={$tmpaddrll6[0]} ";
1777
							} else
1778
								$listen_addresses .= " --listen-address={$laddr6} ";
1779
						}
1780 b4323f39 jim-p
					}
1781
				}
1782
			}
1783
			if (!empty($listen_addresses)) {
1784
				$args .= " {$listen_addresses} ";
1785
				if (isset($config['dnsmasq']['strictbind']))
1786
					$args .= " --bind-interfaces ";
1787
			}
1788
		}
1789
1790 fc27d3f4 Phil Davis
		/* If selected, then first forward reverse lookups for private IPv4 addresses to nowhere. */
1791
		/* If any of these are duplicated by a user-specified domain override (e.g. 10.in-addr.arpa) then */
1792
		/* the user-specified entry made later on the command line below will be the one that is effective. */
1793 0a7985ba Phil Davis
		if (isset($config['dnsmasq']['no_private_reverse'])) {
1794
			/* Note: Carrier Grade NAT (CGN) addresses 100.64.0.0/10 are intentionally not here. */
1795
			/* End-users should not be aware of CGN addresses, so reverse lookups for these should not happen. */
1796
			/* Just the pfSense WAN might get a CGN address from an ISP. */
1797
			$args .= " --server=/10.in-addr.arpa/ ";
1798
			$args .= " --server=/168.192.in-addr.arpa/ ";
1799
			/* Unfortunately the 172.16.0.0/12 range does not map nicely to the in-addr.arpa scheme. */
1800
			for ($subnet_num = 16; $subnet_num < 32; $subnet_num++) { 
1801
				$args .= " --server=/" . $subnet_num . ".172.in-addr.arpa/ ";
1802
			}
1803
		}
1804
1805 fc27d3f4 Phil Davis
		/* Setup forwarded domains */
1806
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1807
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1808
				if ($override['ip'] == "!")
1809
					$override[ip] = "";
1810
				$args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1811
			}
1812
		}
1813
1814 2c46f11f Scott Ullrich
		/* Allow DNS Rebind for forwarded domains */
1815 29721fe6 Scott Ullrich
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1816 30d20e7d Scott Ullrich
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1817
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1818
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1819
				}
1820 2c46f11f Scott Ullrich
			}
1821
		}
1822 91adc5c1 Scott Ullrich
1823 30d20e7d Scott Ullrich
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1824
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1825
1826 96ea7162 N0YB
		if (isset($config['dnsmasq']['strict_order'])) {
1827
			$args .= " --strict-order ";
1828
		}
1829
1830
		if (isset($config['dnsmasq']['domain_needed'])) {
1831
			$args .= " --domain-needed ";
1832
		}
1833
1834 683992fc stilez
		if ($config['dnsmasq']['custom_options'])
1835
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c) {
1836 071f6059 jim-p
				$args .= " " . escapeshellarg("--{$c}");
1837 683992fc stilez
				$p = explode('=', $c);
1838
				if (array_key_exists($p[0], $standard_args))
1839
					unset($standard_args[$p[0]]);
1840
			}
1841 41567e06 jim-p
		$args .= ' ' . implode(' ', array_values($standard_args));
1842 8f9bffbc Andrew Thompson
1843 5b237745 Scott Ullrich
		/* run dnsmasq */
1844 683992fc stilez
		$cmd = "/usr/local/sbin/dnsmasq --all-servers {$dns_rebind} {$args}";
1845 b4323f39 jim-p
		//log_error("dnsmasq command: {$cmd}");
1846
		mwexec_bg($cmd);
1847 928d4416 Ermal
		unset($args);
1848 5b237745 Scott Ullrich
1849
		if ($g['booting'])
1850 f1a44a3a Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1851 5b237745 Scott Ullrich
	}
1852 a25183c5 Scott Ullrich
1853 5b237745 Scott Ullrich
	if (!$g['booting']) {
1854 6a01ea44 Bill Marquette
		if(services_dhcpd_configure()!=0)
1855
			$return = 1;
1856 5b237745 Scott Ullrich
	}
1857
1858 6a01ea44 Bill Marquette
	return $return;
1859 5b237745 Scott Ullrich
}
1860
1861 175dc861 Warren Baker
function services_unbound_configure() {
1862
	global $config, $g;
1863
	$return = 0;
1864
1865
	if (isset($config['system']['developerspew'])) {
1866
		$mt = microtime();
1867
		echo "services_unbound_configure() being called $mt\n";
1868
	}
1869
1870
	// kill any running Unbound instance
1871
	if (file_exists("{$g['varrun_path']}/unbound.pid"))
1872
		sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM");
1873
1874
	if (isset($config['unbound']['enable'])) {
1875
		if ($g['booting'])
1876 5bb1c495 Warren Baker
			echo gettext("Starting DNS Resolver...");
1877 175dc861 Warren Baker
		else
1878
			sleep(1);
1879
1880
		require_once('/etc/inc/unbound.inc');
1881
		sync_unbound_service();
1882
		if ($g['booting'])
1883
			echo gettext("done.") . "\n";
1884
	}
1885
1886
	if (!$g['booting']) {
1887
		if (services_dhcpd_configure()!=0)
1888
			$return = 1;
1889
	}
1890
1891
	return $return;
1892
}
1893
1894 5b237745 Scott Ullrich
function services_snmpd_configure() {
1895 f19d3b7a Scott Ullrich
	global $config, $g;
1896 58c7450e Scott Ullrich
	if(isset($config['system']['developerspew'])) {
1897 acd910bf Scott Ullrich
		$mt = microtime();
1898 f19d3b7a Scott Ullrich
		echo "services_snmpd_configure() being called $mt\n";
1899
	}
1900 5b237745 Scott Ullrich
1901
	/* kill any running snmpd */
1902
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1903 dd18038e Ermal
	sleep(2);
1904 107e8acc Ovidiu Predescu
	if(is_process_running("bsnmpd"))
1905 a976fa82 Scott Ullrich
		mwexec("/usr/bin/killall bsnmpd", true);
1906 5b237745 Scott Ullrich
1907
	if (isset($config['snmpd']['enable'])) {
1908 a25183c5 Scott Ullrich
1909 5b237745 Scott Ullrich
		if ($g['booting'])
1910 f1a44a3a Carlos Eduardo Ramos
			echo gettext("Starting SNMP daemon... ");
1911 5b237745 Scott Ullrich
1912
		/* generate snmpd.conf */
1913
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1914
		if (!$fd) {
1915 f1a44a3a Carlos Eduardo Ramos
			printf(gettext("Error: cannot open snmpd.conf in services_snmpd_configure().%s"),"\n");
1916 5b237745 Scott Ullrich
			return 1;
1917
		}
1918 a25183c5 Scott Ullrich
1919 142da8f7 John Fleming
1920 5b237745 Scott Ullrich
		$snmpdconf = <<<EOD
1921 d47a8a69 Scott Ullrich
location := "{$config['snmpd']['syslocation']}"
1922
contact := "{$config['snmpd']['syscontact']}"
1923
read := "{$config['snmpd']['rocommunity']}"
1924 142da8f7 John Fleming
1925
EOD;
1926
1927
/* No docs on what write strings do there for disable for now.
1928
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1929
		    $snmpdconf .= <<<EOD
1930
# write string
1931
write := "{$config['snmpd']['rwcommunity']}"
1932
1933
EOD;
1934
		}
1935
*/
1936
1937
1938
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1939
		    $snmpdconf .= <<<EOD
1940
# SNMP Trap support.
1941 dbeeb008 John Fleming
traphost := {$config['snmpd']['trapserver']}
1942
trapport := {$config['snmpd']['trapserverport']}
1943
trap := "{$config['snmpd']['trapstring']}"
1944 142da8f7 John Fleming
1945
1946
EOD;
1947
		}
1948
1949 dadf8ebb jim-p
		$version = trim(file_get_contents('/etc/version'));
1950
		$platform = trim(file_get_contents('/etc/platform'));
1951 e52cb3a4 jim-p
		if (($platform == "pfSense") && ($g['product_name'] != "pfSense"))
1952
			$platform = $g['product_name'];
1953 dadf8ebb jim-p
		$sysDescr = "{$g['product_name']} " . php_uname("n") .
1954
			" {$version} {$platform} " . php_uname("s") .
1955
			" " . php_uname("r") . " " . php_uname("m");
1956 142da8f7 John Fleming
1957
		$snmpdconf .= <<<EOD
1958 d47a8a69 Scott Ullrich
system := 1     # pfSense
1959
%snmpd
1960 dadf8ebb jim-p
sysDescr			= "{$sysDescr}"
1961 d47a8a69 Scott Ullrich
begemotSnmpdDebugDumpPdus       = 2
1962
begemotSnmpdDebugSyslogPri      = 7
1963
begemotSnmpdCommunityString.0.1 = $(read)
1964 142da8f7 John Fleming
1965
EOD;
1966
1967
/* No docs on what write strings do there for disable for now.
1968
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1969
		    $snmpdconf .= <<<EOD
1970
begemotSnmpdCommunityString.0.2 = $(write)
1971
1972
EOD;
1973
		}
1974
*/
1975
1976 c7f44ae0 Scott Ullrich
1977 142da8f7 John Fleming
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1978
		    $snmpdconf .= <<<EOD
1979
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1980
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1981
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1982
1983
EOD;
1984
		}
1985
1986
1987
		$snmpdconf .= <<<EOD
1988 d47a8a69 Scott Ullrich
begemotSnmpdCommunityDisable    = 1
1989 03ba7a0f John Fleming
1990
EOD;
1991
1992 de5aec97 jim-p
		if (isset($config['snmpd']['bindlan'])) {
1993
			$config['snmpd']['bindip'] = 'lan';
1994
			unset($config['snmpd']['bindlan']);
1995
		}
1996 c82b2c3f jim-p
		$bind_to_ip = "0.0.0.0";
1997
		if(isset($config['snmpd']['bindip'])) {
1998
			if (is_ipaddr($config['snmpd']['bindip'])) {
1999
				$bind_to_ip = $config['snmpd']['bindip'];
2000
			} else {
2001
				$if = get_real_interface($config['snmpd']['bindip']);
2002
				if (does_interface_exist($if))
2003
					$bind_to_ip = find_interface_ip($if);
2004
			}
2005 7cbad422 Scott Ullrich
		}
2006
2007 03ba7a0f John Fleming
		if(is_port( $config['snmpd']['pollport'] )) {
2008
		    $snmpdconf .= <<<EOD
2009 7cbad422 Scott Ullrich
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
2010 03ba7a0f John Fleming
2011
EOD;
2012
2013
		}
2014
2015
		$snmpdconf .= <<<EOD
2016 d47a8a69 Scott Ullrich
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
2017
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
2018 142da8f7 John Fleming
2019 03ba7a0f John Fleming
# These are bsnmp macros not php vars.
2020 9cc8c59e Scott Ullrich
sysContact      = $(contact)
2021
sysLocation     = $(location)
2022
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
2023 142da8f7 John Fleming
2024 d47a8a69 Scott Ullrich
snmpEnableAuthenTraps = 2
2025 03ba7a0f John Fleming
2026
EOD;
2027
2028
		if (is_array( $config['snmpd']['modules'] )) {
2029
		    if(isset($config['snmpd']['modules']['mibii'])) {
2030
			$snmpdconf .= <<<EOD
2031 d47a8a69 Scott Ullrich
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
2032 03ba7a0f John Fleming
2033
EOD;
2034
		    }
2035
2036
		    if(isset($config['snmpd']['modules']['netgraph'])) {
2037
			$snmpdconf .= <<<EOD
2038 d47a8a69 Scott Ullrich
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
2039
%netgraph
2040
begemotNgControlNodeName = "snmpd"
2041 03ba7a0f John Fleming
2042
EOD;
2043
		    }
2044
2045
		    if(isset($config['snmpd']['modules']['pf'])) {
2046
			$snmpdconf .= <<<EOD
2047 d47a8a69 Scott Ullrich
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
2048 95fb49e8 Seth Mos
2049
EOD;
2050
		    }
2051
2052
		    if(isset($config['snmpd']['modules']['hostres'])) {
2053
			$snmpdconf .= <<<EOD
2054
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
2055
2056
EOD;
2057
		    }
2058
		    if(isset($config['snmpd']['modules']['bridge'])) {
2059
			$snmpdconf .= <<<EOD
2060
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
2061 d47a8a69 Scott Ullrich
# config must end with blank line
2062 5b237745 Scott Ullrich
2063
EOD;
2064 03ba7a0f John Fleming
		    }
2065 671914b2 jim-p
			if(isset($config['snmpd']['modules']['ucd'])) {
2066
				$snmpdconf .= <<<EOD
2067
begemotSnmpdModulePath."ucd"     = "/usr/local/lib/snmp_ucd.so"
2068
2069
EOD;
2070
			}
2071
			if(isset($config['snmpd']['modules']['regex'])) {
2072
				$snmpdconf .= <<<EOD
2073
begemotSnmpdModulePath."regex"     = "/usr/local/lib/snmp_regex.so"
2074
2075
EOD;
2076
			}
2077 03ba7a0f John Fleming
		}
2078 5b237745 Scott Ullrich
2079
		fwrite($fd, $snmpdconf);
2080
		fclose($fd);
2081 928d4416 Ermal
		unset($snmpdconf);
2082 5b237745 Scott Ullrich
2083 7cbad422 Scott Ullrich
		if (isset($config['snmpd']['bindlan'])) {
2084
			$bindlan = "";
2085
		}
2086
2087 853e003a Scott Ullrich
		/* run bsnmpd */
2088
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
2089 7cbad422 Scott Ullrich
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
2090 5b237745 Scott Ullrich
2091
		if ($g['booting'])
2092 f1a44a3a Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
2093 5b237745 Scott Ullrich
	}
2094
2095
	return 0;
2096
}
2097
2098 7c9da7be jim-p
function services_dnsupdate_process($int = "", $updatehost = "", $forced = false) {
2099 f19d3b7a Scott Ullrich
	global $config, $g;
2100 58c7450e Scott Ullrich
	if(isset($config['system']['developerspew'])) {
2101 acd910bf Scott Ullrich
		$mt = microtime();
2102 f19d3b7a Scott Ullrich
		echo "services_dnsupdate_process() being called $mt\n";
2103 acd910bf Scott Ullrich
	}
2104 f19d3b7a Scott Ullrich
2105 a23d7248 Scott Ullrich
	/* Dynamic DNS updating active? */
2106 67ee1ec5 Ermal Luçi
	if (is_array($config['dnsupdates']['dnsupdate'])) {
2107 7c9da7be jim-p
		$notify_text = "";
2108 67ee1ec5 Ermal Luçi
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
2109 26586f7a Ermal Lu?i
			if (!isset($dnsupdate['enable']))
2110 2ec2a374 Ermal Lu?i
				continue;
2111 26586f7a Ermal Lu?i
			if (!empty($int) && $int != $dnsupdate['interface'])
2112 67ee1ec5 Ermal Luçi
				continue;
2113 7c9da7be jim-p
			if (!empty($updatehost) && ($updatehost != $dnsupdate['host']))
2114
				continue;
2115 67ee1ec5 Ermal Luçi
2116 2ec2a374 Ermal Lu?i
			/* determine interface name */
2117 26586f7a Ermal Lu?i
			$if = get_real_interface($dnsupdate['interface']);
2118 09cb9dee Florian Asche
			
2119
			if (isset($dnsupdate['usepublicip']))
2120
                                $wanip = dyndnsCheckIP($dnsupdate['interface']);
2121
                        else
2122
                                $wanip = get_interface_ip($dnsupdate['interface']);
2123
			
2124 fc1f4960 jim-p
			$wanipv6 = get_interface_ipv6($dnsupdate['interface']);
2125 7c9da7be jim-p
			$cacheFile = "{$g['conf_path']}/dyndns_{$dnsupdate['interface']}_rfc2136_" . escapeshellarg($dnsupdate['host']) . "_{$dnsupdate['server']}.cache";
2126
			$currentTime = time();
2127
2128
			if ($wanip || $wanipv6) {
2129 67ee1ec5 Ermal Luçi
				$keyname = $dnsupdate['keyname'];
2130
				/* trailing dot */
2131
				if (substr($keyname, -1) != ".")
2132
					$keyname .= ".";
2133
2134
				$hostname = $dnsupdate['host'];
2135
				/* trailing dot */
2136
				if (substr($hostname, -1) != ".")
2137
					$hostname .= ".";
2138
2139
				/* write private key file
2140
				   this is dumb - public and private keys are the same for HMAC-MD5,
2141
				   but nsupdate insists on having both */
2142
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
2143 8ec0a8bc jim-p
				$privkey = <<<EOD
2144 a23d7248 Scott Ullrich
Private-key-format: v1.2
2145
Algorithm: 157 (HMAC)
2146 67ee1ec5 Ermal Luçi
Key: {$dnsupdate['keydata']}
2147 a23d7248 Scott Ullrich
2148
EOD;
2149 67ee1ec5 Ermal Luçi
				fwrite($fd, $privkey);
2150
				fclose($fd);
2151
2152
				/* write public key file */
2153
				if ($dnsupdate['keytype'] == "zone") {
2154
					$flags = 257;
2155
					$proto = 3;
2156
				} else if ($dnsupdate['keytype'] == "host") {
2157
					$flags = 513;
2158
					$proto = 3;
2159
				} else if ($dnsupdate['keytype'] == "user") {
2160
					$flags = 0;
2161
					$proto = 2;
2162
				}
2163 c7f44ae0 Scott Ullrich
2164 26586f7a Ermal Lu?i
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.key", "w");
2165 67ee1ec5 Ermal Luçi
				fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n");
2166
				fclose($fd);
2167
2168
				/* generate update instructions */
2169
				$upinst = "";
2170
				if (!empty($dnsupdate['server']))
2171
					$upinst .= "server {$dnsupdate['server']}\n";
2172 7c9da7be jim-p
2173
				if (file_exists($cacheFile)) {
2174
					list($cachedipv4, $cacheTimev4) = explode("|", file_get_contents($cacheFile));
2175
				}
2176
				if (file_exists("{$cacheFile}.ipv6")) {
2177
					list($cachedipv6, $cacheTimev6) = explode("|", file_get_contents("{$cacheFile}.ipv6"));
2178
				}
2179
2180
				// 25 Days
2181
				$maxCacheAgeSecs = 25 * 24 * 60 * 60;
2182
				$need_update = false;
2183 819a603c jim-p
2184
				conf_mount_rw();
2185 fc1f4960 jim-p
				/* Update IPv4 if we have it. */
2186
				if (is_ipaddrv4($wanip)) {
2187 7c9da7be jim-p
					if (($wanip != $cachedipv4) || (($currentTime - $cacheTimev4) > $maxCacheAgeSecs) || $forced) {
2188
						$upinst .= "update delete {$dnsupdate['host']}. A\n";
2189
						$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} A {$wanip}\n";
2190
						$notify_text .= sprintf(gettext("DynDNS updated IP Address (A) for {$dnsupdate['host']} on %s (%s) to %s"), convert_real_interface_to_friendly_descr($if), $if, $wanip) . "\n";
2191
						@file_put_contents($cacheFile, "{$wanip}|{$currentTime}");
2192
						log_error("phpDynDNS: updating cache file {$cacheFile}: {$wanip}");
2193
						$need_update = true;
2194
					} else {
2195
						log_error("phpDynDNS: Not updating {$dnsupdate['host']} A record because the IP address has not changed.");
2196
					}
2197
				} else
2198
					@unlink($cacheFile);
2199
2200 fc1f4960 jim-p
				/* Update IPv6 if we have it. */
2201
				if (is_ipaddrv6($wanipv6)) {
2202 7c9da7be jim-p
					if (($wanipv6 != $cachedipv6) || (($currentTime - $cacheTimev6) > $maxCacheAgeSecs) || $forced) {
2203
						$upinst .= "update delete {$dnsupdate['host']}. AAAA\n";
2204
						$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} AAAA {$wanipv6}\n";
2205
						$notify_text .= sprintf(gettext("DynDNS updated IPv6 Address (AAAA) for {$dnsupdate['host']} on %s (%s) to %s"), convert_real_interface_to_friendly_descr($if), $if, $wanipv6) . "\n";
2206
						@file_put_contents("{$cacheFile}.ipv6", "{$wanipv6}|{$currentTime}");
2207
						log_error("phpDynDNS: updating cache file {$cacheFile}.ipv6: {$wanipv6}");
2208
						$need_update = true;
2209
					} else {
2210
						log_error("phpDynDNS: Not updating {$dnsupdate['host']} AAAA record because the IPv6 address has not changed.");
2211
					}
2212
				} else
2213
					@unlink("{$cacheFile}.ipv6");
2214 819a603c jim-p
				conf_mount_ro();
2215 67ee1ec5 Ermal Luçi
2216 7c9da7be jim-p
				$upinst .= "\n";	/* mind that trailing newline! */
2217 107e8acc Ovidiu Predescu
2218 7c9da7be jim-p
				if ($need_update) {
2219
					@file_put_contents("{$g['varetc_path']}/nsupdatecmds{$i}", $upinst);
2220
					unset($upinst);
2221
					/* invoke nsupdate */
2222 22cc6582 Renato Botelho
					$cmd = "/usr/local/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
2223 7c9da7be jim-p
					if (isset($dnsupdate['usetcp']))
2224
						$cmd .= " -v";
2225
					$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
2226
					mwexec_bg($cmd);
2227
					unset($cmd);
2228
				}
2229 67ee1ec5 Ermal Luçi
			}
2230 a23d7248 Scott Ullrich
		}
2231 7c9da7be jim-p
		if (!empty($notify_text)) {
2232
			notify_all_remote($notify_text);
2233
		}
2234 a23d7248 Scott Ullrich
	}
2235 c7f44ae0 Scott Ullrich
2236 a23d7248 Scott Ullrich
	return 0;
2237 5b237745 Scott Ullrich
}
2238
2239 1071e028 Scott Ullrich
/* configure cron service */
2240
function configure_cron() {
2241
	global $g, $config;
2242 e7d3fc15 Ermal
2243 251ca022 Scott Ullrich
	conf_mount_rw();
2244 1071e028 Scott Ullrich
	/* preserve existing crontab entries */
2245 e7d3fc15 Ermal
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2246 107e8acc Ovidiu Predescu
2247 e7d3fc15 Ermal
	for ($i = 0; $i < count($crontab_contents); $i++) {
2248
		$cron_item =& $crontab_contents[$i];
2249
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
2250
			array_splice($crontab_contents, $i - 1);
2251 1071e028 Scott Ullrich
			break;
2252
		}
2253
	}
2254 e7d3fc15 Ermal
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
2255 107e8acc Ovidiu Predescu
2256
2257 1071e028 Scott Ullrich
	if (is_array($config['cron']['item'])) {
2258
		$crontab_contents .= "#\n";
2259 f1a44a3a Carlos Eduardo Ramos
		$crontab_contents .= "# " . gettext("pfSense specific crontab entries") . "\n";
2260
		$crontab_contents .= "# " .gettext( "Created:") . " " . date("F j, Y, g:i a") . "\n";
2261 1071e028 Scott Ullrich
		$crontab_contents .= "#\n";
2262
2263
		foreach ($config['cron']['item'] as $item) {
2264
			$crontab_contents .= "\n{$item['minute']}\t";
2265
			$crontab_contents .= "{$item['hour']}\t";
2266
			$crontab_contents .= "{$item['mday']}\t";
2267
			$crontab_contents .= "{$item['month']}\t";
2268
			$crontab_contents .= "{$item['wday']}\t";
2269
			$crontab_contents .= "{$item['who']}\t";
2270
			$crontab_contents .= "{$item['command']}";
2271
		}
2272 107e8acc Ovidiu Predescu
2273 1071e028 Scott Ullrich
		$crontab_contents .= "\n#\n";
2274 f1a44a3a Carlos Eduardo Ramos
		$crontab_contents .= "# " . gettext("If possible do not add items to this file manually.") . "\n";
2275
		$crontab_contents .= "# " . gettext("If you do so, this file must be terminated with a blank line (e.g. new line)") . "\n";
2276 1071e028 Scott Ullrich
		$crontab_contents .= "#\n\n";
2277
	}
2278 107e8acc Ovidiu Predescu
2279 1071e028 Scott Ullrich
	/* please maintain the newline at the end of file */
2280
	file_put_contents("/etc/crontab", $crontab_contents);
2281 c2d97111 Ermal
	unset($crontab_contents);
2282 41d507a5 Scott Ullrich
2283
	/* do a HUP kill to force sync changes */
2284 dca795b7 Renato Botelho
	sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
2285 41d507a5 Scott Ullrich
2286 6d6bca27 Ermal Lu?i
	conf_mount_ro();
2287 1071e028 Scott Ullrich
}
2288
2289 431484c8 Ryan Wagoner
function upnp_action ($action) {
2290 aa6798c0 Scott Ullrich
	global $g, $config;
2291 431484c8 Ryan Wagoner
	switch($action) {
2292
		case "start":
2293 c1ac2424 Ermal
			if (file_exists('/var/etc/miniupnpd.conf')) {
2294
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
2295
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
2296
			}
2297 431484c8 Ryan Wagoner
			break;
2298
		case "stop":
2299 c1ac2424 Ermal
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
2300 05c4bfa0 Ermal
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
2301 73239086 Seth Mos
				mwexec('killall miniupnpd 2>/dev/null', true);
2302 431484c8 Ryan Wagoner
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
2303
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
2304
			break;
2305
		case "restart":
2306
			upnp_action('stop');
2307
			upnp_action('start');
2308
			break;
2309
	}
2310
}
2311
2312 6f20377b Scott Ullrich
function upnp_start() {
2313 dcc897e5 Ermal
	global $config;
2314 0c331f1e Ermal Lu?i
2315
	if(!isset($config['installedpackages']['miniupnpd']['config']))
2316
		return;
2317
2318 431484c8 Ryan Wagoner
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
2319 54bdff75 Vinicius Coque
		echo gettext("Starting UPnP service... ");
2320 dcc897e5 Ermal
		require_once('/usr/local/pkg/miniupnpd.inc');
2321
		sync_package_miniupnpd();
2322
		echo "done.\n";
2323 6f20377b Scott Ullrich
	}
2324
}
2325
2326 85405c11 jim-p
function install_cron_job($command, $active=false, $minute="0", $hour="*", $monthday="*", $month="*", $weekday="*", $who="root") {
2327
	global $config, $g;
2328
2329
	$is_installed = false;
2330
2331 c2d97111 Ermal
	if (!is_array($config['cron']))
2332
		$config['cron'] = array();
2333
	if (!is_array($config['cron']['item']))
2334
		$config['cron']['item'] = array();
2335 85405c11 jim-p
2336
	$x=0;
2337
	foreach($config['cron']['item'] as $item) {
2338
		if(strstr($item['command'], $command)) {
2339
			$is_installed = true;
2340
			break;
2341
		}
2342
		$x++;
2343
	}
2344
2345
	if($active) {
2346
		$cron_item = array();
2347
		$cron_item['minute'] = $minute;
2348
		$cron_item['hour'] = $hour;
2349
		$cron_item['mday'] = $monthday;
2350
		$cron_item['month'] = $month;
2351
		$cron_item['wday'] = $weekday;
2352
		$cron_item['who'] = $who;
2353
		$cron_item['command'] = $command;
2354
		if(!$is_installed) {
2355
			$config['cron']['item'][] = $cron_item;
2356 f1a44a3a Carlos Eduardo Ramos
			write_config(sprintf(gettext("Installed cron job for %s"), $command));
2357 85405c11 jim-p
		} else {
2358
			$config['cron']['item'][$x] = $cron_item;
2359 f1a44a3a Carlos Eduardo Ramos
			write_config(sprintf(gettext("Updated cron job for %s"), $command));
2360 85405c11 jim-p
		}
2361
	} else {
2362 0b5636fc jim-p
		if($is_installed == true) {
2363 85405c11 jim-p
			unset($config['cron']['item'][$x]);
2364 149ed85e bcyrill
			write_config(sprintf(gettext("Removed cron job for %s"), $command));
2365 85405c11 jim-p
		}
2366
	}
2367
	configure_cron();
2368
}
2369
2370 693833cb Seth Mos
?>