Project

General

Profile

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