Project

General

Profile

Download (67.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	system.inc
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31

    
32
/*
33
	pfSense_BUILDER_BINARIES:	/usr/sbin/powerd	/usr/bin/killall	/sbin/route
34
	pfSense_BUILDER_BINARIES:	/bin/hostname	/bin/ls	/usr/sbin/syslogd	
35
	pfSense_BUILDER_BINARIES:	/usr/sbin/pccardd	/usr/local/sbin/lighttpd	/bin/chmod 	/bin/mkdir
36
	pfSense_BUILDER_BINARIES:	/usr/bin/tar		/usr/local/sbin/ntpd	/usr/local/sbin/ntpdate
37
	pfSense_BUILDER_BINARIES:	/usr/bin/nohup	/sbin/dmesg	/usr/local/sbin/atareinit	/sbin/kldload
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns
39
	pfSense_MODULE:	utils
40
*/
41

    
42
function activate_powerd() {
43
	global $config, $g;
44
	if ($g['platform'] == 'jail')
45
		return;
46
	if(is_process_running("powerd"))
47
		exec("/usr/bin/killall powerd");
48
	if(isset($config['system']['powerd_enable'])) {
49
		if ($g["platform"] == "nanobsd")
50
			exec("/sbin/kldload cpufreq");
51

    
52
		$ac_mode = "hadp";
53
		if (!empty($config['system']['powerd_ac_mode']))
54
			$ac_mode = $config['system']['powerd_ac_mode'];
55

    
56
		$battery_mode = "hadp";
57
		if (!empty($config['system']['powerd_battery_mode']))
58
			$battery_mode = $config['system']['powerd_battery_mode'];
59

    
60
		$normal_mode = "hadp";
61
		if (!empty($config['system']['powerd_normal_mode']))
62
			$normal_mode = $config['system']['powerd_normal_mode'];
63

    
64
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
65
	}
66
}
67

    
68
function get_default_sysctl_value($id) {
69
	global $sysctls;
70

    
71
	if (isset($sysctls[$id]))
72
		return $sysctls[$id];
73
}
74

    
75
function get_sysctl_descr($sysctl) {
76
	unset($output);
77
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
78

    
79
	return $output[0];
80
}
81

    
82
function system_get_sysctls() {
83
	global $config, $sysctls;
84

    
85
	$disp_sysctl = array();
86
	$disp_cache = array();
87
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
88
		foreach($config['sysctl']['item'] as $id => $tunable) {
89
			if ($tunable['value'] == "default")
90
				$value = get_default_sysctl_value($tunable['tunable']);
91
			else
92
				$value = $tunable['value'];
93

    
94
			$disp_sysctl[$id] = $tunable;
95
			$disp_sysctl[$id]['modified'] = true;
96
			$disp_cache[$tunable['tunable']] = 'set';
97
		}
98
	}
99

    
100
	foreach ($sysctls as $sysctl => $value) {
101
		if (isset($disp_cache[$sysctl]))
102
			continue;
103

    
104
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
105
	}
106
	unset($disp_cache);
107
	return $disp_sysctl;
108
}
109

    
110
function activate_sysctls() {
111
	global $config, $g, $sysctls;
112

    
113
	if ($g['platform'] == 'jail')
114
		return;
115

    
116
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
117
		foreach($config['sysctl']['item'] as $tunable) {
118
			if($tunable['value'] == "default")
119
				$value = get_default_sysctl_value($tunable['tunable']);
120
			else
121
				$value = $tunable['value'];
122

    
123
			$sysctls[$tunable['tunable']] = $value;
124
		}
125
	}
126

    
127
	set_sysctl($sysctls);
128
}
129

    
130
function system_resolvconf_generate($dynupdate = false) {
131
	global $config, $g;
132

    
133
	if(isset($config['system']['developerspew'])) {
134
		$mt = microtime();
135
		echo "system_resolvconf_generate() being called $mt\n";
136
	}
137

    
138
	$syscfg = $config['system'];
139

    
140
	if (((isset($config['dnsmasq']['enable']) && (!isset($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") && (empty($config['dnsmasq']['interface']) || in_array("lo0", explode(",", $config['dnsmasq']['interface']))))
141
		|| (isset($config['unbound']['enable'])) && (!isset($config['unbound']['port']) || $config['unbound']['port'] == "53") && (empty($config['unbound']['active_interface']) || in_array("lo0", explode(",", $config['unbound']['active_interface'])) || in_array("all", explode(",", $config['unbound']['active_interface']), true)))
142
		&& !isset($config['system']['dnslocalhost']))
143
		$resolvconf .= "nameserver 127.0.0.1\n";
144

    
145
	if (isset($syscfg['dnsallowoverride'])) {
146
		/* get dynamically assigned DNS servers (if any) */
147
		$ns = array_unique(get_searchdomains());
148
		foreach($ns as $searchserver) {
149
			if($searchserver)
150
				$resolvconf .= "search {$searchserver}\n";
151
		}
152
		$ns = array_unique(get_nameservers());
153
		foreach($ns as $nameserver) {
154
			if($nameserver)
155
				$resolvconf .= "nameserver $nameserver\n";
156
		}
157
	} else {
158
		$ns = array();
159
		// Do not create blank search/domain lines, it can break tools like dig.
160
		if($syscfg['domain'])
161
			$resolvconf .= "search {$syscfg['domain']}\n";
162
	}
163
	if (is_array($syscfg['dnsserver'])) {
164
		foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
165
			if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
166
				$resolvconf .= "nameserver $sys_dnsserver\n";
167
			}
168
		}
169
	}
170

    
171
	// Add EDNS support
172
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns']))
173
		$resolvconf .= "options edns0\n";
174

    
175
	$dnslock = lock('resolvconf', LOCK_EX);
176

    
177
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
178
	if (!$fd) {
179
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
180
		unlock($dnslock);
181
		return 1;
182
	}
183

    
184
	fwrite($fd, $resolvconf);
185
	fclose($fd);
186

    
187
	// Prevent resolvconf(8) from rewriting our resolv.conf
188
	$fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
189
	if (!$fd) {
190
		printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
191
		return 1;
192
	}
193
	fwrite($fd, "resolv_conf=\"/dev/null\"\n");
194
	fclose($fd);
195

    
196
	if (!platform_booting()) {
197
		/* restart dhcpd (nameservers may have changed) */
198
		if (!$dynupdate)
199
			services_dhcpd_configure();
200
	}
201

    
202
	/* setup static routes for DNS servers. */
203
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
204
		/* setup static routes for dns servers */
205
		$dnsgw = "dns{$dnscounter}gw";
206
		if (isset($config['system'][$dnsgw])) {
207
			$gwname = $config['system'][$dnsgw];
208
			if (($gwname <> "") && ($gwname <> "none")) {
209
				$gatewayip = lookup_gateway_ip_by_name($gwname);
210
				if (is_ipaddrv4($gatewayip)) {
211
					/* dns server array starts at 0 */
212
					$dnscountermo = $dnscounter - 1;
213
					mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
214
					if (isset($config['system']['route-debug'])) {
215
						$mt = microtime();
216
						log_error("ROUTING debug: $mt - route change -host {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
217
					}
218
				}
219
				if (is_ipaddrv6($gatewayip)) {
220
					/* dns server array starts at 0 */
221
					$dnscountermo = $dnscounter - 1;
222
					mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
223
					if (isset($config['system']['route-debug'])) {
224
						$mt = microtime();
225
						log_error("ROUTING debug: $mt - route change -host -inet6 {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
226
					}					
227
				}
228
			}
229
		}
230
	}
231

    
232
	unlock($dnslock);
233

    
234
	return 0;
235
}
236

    
237
function get_searchdomains() {
238
	global $config, $g;
239

    
240
	$master_list = array();
241
	
242
	// Read in dhclient nameservers
243
	$search_list = glob("/var/etc/searchdomain_*");
244
	if (is_array($search_list)) {
245
		foreach($search_list as $fdns) {
246
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
247
			if (!is_array($contents))
248
				continue;
249
			foreach ($contents as $dns) {
250
				if(is_hostname($dns)) 
251
					$master_list[] = $dns;
252
			}
253
		}
254
	}
255

    
256
	return $master_list;
257
}
258

    
259
function get_nameservers() {
260
	global $config, $g;
261
	$master_list = array();
262
	
263
	// Read in dhclient nameservers
264
	$dns_lists = glob("/var/etc/nameserver_*");
265
	if (is_array($dns_lists)) {
266
		foreach($dns_lists as $fdns) {
267
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
268
			if (!is_array($contents))
269
				continue;
270
			foreach ($contents as $dns) {
271
				if(is_ipaddr($dns)) 
272
					$master_list[] = $dns;
273
			}
274
		}
275
	}
276

    
277
	// Read in any extra nameservers
278
	if(file_exists("/var/etc/nameservers.conf")) {
279
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
280
		if(is_array($dns_s)) {
281
			foreach($dns_s as $dns)
282
				if (is_ipaddr($dns))
283
					$master_list[] = $dns;
284
		}
285
	}
286

    
287
	return $master_list;
288
}
289

    
290
function system_hosts_generate() {
291
	global $config, $g;
292
	if (isset($config['system']['developerspew'])) {
293
		$mt = microtime();
294
		echo "system_hosts_generate() being called $mt\n";
295
	}
296

    
297
	$syscfg = $config['system'];
298
	if (isset($config['unbound']) && isset($config['unbound']['enable']))
299
		$dnsmasqcfg = $config['unbound'];
300
	else
301
		$dnsmasqcfg = $config['dnsmasq'];
302

    
303
	$hosts =  "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
304
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
305
	$lhosts = "";
306
	$dhosts = "";
307

    
308
	if ($config['interfaces']['lan']) {
309
		$cfgip = get_interface_ip("lan");
310
		if (is_ipaddr($cfgip))
311
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
312
		$cfgipv6 = get_interface_ipv6("lan");
313
		if (is_ipaddrv6($cfgipv6))
314
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
315
	} else {
316
		$sysiflist = get_configured_interface_list();
317
		$hosts_if_found = false;
318
		foreach ($sysiflist as $sysif) {
319
			if (!interface_has_gateway($sysif)) {
320
				$cfgip = get_interface_ip($sysif);
321
				if (is_ipaddr($cfgip)) {
322
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
323
					$hosts_if_found = true;
324
				}
325
				$cfgipv6 = get_interface_ipv6($sysif);
326
				if (is_ipaddrv6($cfgipv6)) {
327
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
328
					$hosts_if_found = true;
329
				}
330
				if ($hosts_if_found == true)
331
					break;
332
			}
333
		}
334
	}
335

    
336
	if (isset($dnsmasqcfg['enable'])) {
337
		if (!is_array($dnsmasqcfg['hosts']))
338
			$dnsmasqcfg['hosts'] = array();
339

    
340
		foreach ($dnsmasqcfg['hosts'] as $host) {
341
			if ($host['host'] || $host['host'] == "0")
342
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
343
			else
344
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
345
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item']))
346
				continue;
347
			foreach ($host['aliases']['item'] as $alias) {
348
				if ($alias['host'] || $alias['host'] == "0")
349
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
350
				else
351
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
352
			}
353
		}
354
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
355
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf)
356
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
357
						foreach ($dhcpifconf['staticmap'] as $host)
358
							if ($host['ipaddr'] && $host['hostname'] && $host['domain'])
359
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
360
							else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain'])
361
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
362
							else if ($host['ipaddr'] && $host['hostname'])
363
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
364
		}
365
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
366
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf)
367
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
368
						foreach ($dhcpifconf['staticmap'] as $host)
369
							if ($host['ipaddrv6'] && $host['hostname'] && $host['domain'])
370
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
371
							else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain'])
372
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
373
							else if ($host['ipaddrv6'] && $host['hostname'])
374
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
375
		}
376

    
377
		if (isset($dnsmasqcfg['dhcpfirst']))
378
			$hosts .= $dhosts . $lhosts;
379
		else
380
			$hosts .= $lhosts . $dhosts;
381
	}
382

    
383
	/*
384
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be 
385
	 * killed before writing to hosts files.
386
	 */
387
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
388
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
389
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
390
	}
391
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
392
	if (!$fd) {
393
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
394
		return 1;
395
	}
396
	fwrite($fd, $hosts);
397
	fclose($fd);
398

    
399
	if (isset($config['unbound']['enable'])) {
400
		require_once("unbound.inc");
401
		unbound_hosts_generate();
402
	}
403

    
404
	return 0;
405
}
406

    
407
function system_dhcpleases_configure() {
408
	global $config, $g;
409
	
410
	if ($g['platform'] == 'jail')
411
		return;
412
	/* Start the monitoring process for dynamic dhcpclients. */
413
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) 
414
		|| (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
415
		/* Make sure we do not error out */
416
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
417
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"))
418
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
419

    
420
		if (isset($config['unbound']['enable'])) {
421
			$dns_pid = "unbound.pid";
422
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
423
		} else {
424
			$dns_pid = "dnsmasq.pid";
425
			$unbound_conf = "";
426
		}
427

    
428
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
429
		if (isvalidpid($pidfile)) {
430
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
431
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
432
			if (intval($retval) == 0) {
433
				sigkillbypid($pidfile, "HUP");
434
				return;
435
			} else
436
				sigkillbypid($pidfile, "TERM");
437
		}
438

    
439
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
440
		if (is_process_running("dhcpleases"))
441
			sigkillbyname('dhcpleases', "TERM");
442
		@unlink($pidfile);
443
		mwexec("/usr/local/sbin/dhcpleases -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases -d {$config['system']['domain']} -p {$g['varrun_path']}/{$dns_pid} {$unbound_conf} -h {$g['varetc_path']}/hosts");
444
	} else {
445
		sigkillbypid($pidfile, "TERM");
446
		@unlink($pidfile);
447
	}
448
}
449

    
450
function system_hostname_configure() {
451
	global $config, $g;
452
	if(isset($config['system']['developerspew'])) {
453
		$mt = microtime();
454
		echo "system_hostname_configure() being called $mt\n";
455
	}
456

    
457
	$syscfg = $config['system'];
458

    
459
	/* set hostname */
460
	$status = mwexec("/bin/hostname " .
461
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
462

    
463
    /* Setup host GUID ID.  This is used by ZFS. */
464
	mwexec("/etc/rc.d/hostid start");
465

    
466
	return $status;
467
}
468

    
469
function system_routing_configure($interface = "") {
470
	global $config, $g;
471
	if ($g['platform'] == 'jail')
472
		return;
473
	if(isset($config['system']['developerspew'])) {
474
		$mt = microtime();
475
		echo "system_routing_configure() being called $mt\n";
476
	}
477

    
478
	$gatewayip = "";
479
	$interfacegw = "";
480
	$gatewayipv6 = "";
481
	$interfacegwv6 = "";
482
	$foundgw = false;
483
	$foundgwv6 = false;
484
	/* tack on all the hard defined gateways as well */
485
	if (is_array($config['gateways']['gateway_item'])) {
486
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
487
		foreach	($config['gateways']['gateway_item'] as $gateway) {
488
			if (isset($gateway['defaultgw'])) {
489
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
490
					if(strpos($gateway['gateway'], ":"))
491
						continue;
492
					if ($gateway['gateway'] == "dynamic")
493
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
494
					$gatewayip = $gateway['gateway'];
495
					$interfacegw = $gateway['interface'];
496
					if (!empty($gateway['interface'])) {
497
						$defaultif = get_real_interface($gateway['interface']);
498
						if ($defaultif)
499
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
500
					}
501
					$foundgw = true;
502
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
503
					if ($gateway['gateway'] == "dynamic")
504
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
505
					$gatewayipv6 = $gateway['gateway'];
506
					$interfacegwv6 = $gateway['interface'];
507
					if (!empty($gateway['interface'])) {
508
						$defaultifv6 = get_real_interface($gateway['interface']);
509
						if ($defaultifv6)
510
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
511
					}
512
					$foundgwv6 = true;
513
				}
514
			}
515
			if ($foundgw === true && $foundgwv6 === true)
516
				break;
517
		}
518
	}
519
	if ($foundgw == false) {
520
		$defaultif = get_real_interface("wan");
521
		$interfacegw = "wan";
522
		$gatewayip = get_interface_gateway("wan");
523
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
524
	}	
525
	if ($foundgwv6 == false) {
526
		$defaultifv6 = get_real_interface("wan");
527
		$interfacegwv6 = "wan";
528
		$gatewayipv6 = get_interface_gateway_v6("wan");
529
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
530
	}
531
	$dont_add_route = false;
532
	/* if OLSRD is enabled, allow WAN to house DHCP. */
533
	if (is_array($config['installedpackages']['olsrd'])) {
534
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
535
			if(($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
536
				$dont_add_route = true;
537
				log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
538
				break;
539
			}
540
		}
541
	}
542

    
543
	if ($dont_add_route == false ) {
544
		if (!empty($interface) && $interface != $interfacegw)
545
			;
546
		else if (is_ipaddrv4($gatewayip)) {
547
			log_error("ROUTING: setting default route to $gatewayip");
548
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
549
		}
550

    
551
		if (!empty($interface) && $interface != $interfacegwv6)
552
			;
553
		else if (is_ipaddrv6($gatewayipv6)) {
554
			$ifscope = "";
555
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%'))
556
				$ifscope = "%{$defaultifv6}";
557
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
558
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
559
		}
560
	}
561

    
562
	system_staticroutes_configure($interface, false);
563

    
564
	return 0;
565
}
566

    
567
function system_staticroutes_configure($interface = "", $update_dns = false) {
568
	global $config, $g, $aliastable;
569

    
570
	$filterdns_list = array();
571

    
572
	$static_routes = get_staticroutes(false, true);
573
	if (count($static_routes)) {
574
		$gateways_arr = return_gateways_array(false, true);
575

    
576
		foreach ($static_routes as $rtent) {
577
			if (empty($gateways_arr[$rtent['gateway']])) {
578
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
579
				continue;
580
			}
581
			$gateway = $gateways_arr[$rtent['gateway']];
582
			if (!empty($interface) && $interface != $gateway['friendlyiface'])
583
				continue;
584

    
585
			$gatewayip = $gateway['gateway'];
586
			$interfacegw = $gateway['interface'];
587

    
588
			$blackhole = "";
589
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3)))
590
				$blackhole = "-blackhole";
591

    
592
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network']))
593
				continue;
594

    
595
			$dnscache = array();
596
			if ($update_dns === true) {
597
				if (is_subnet($rtent['network']))
598
					continue;
599
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
600
				if (empty($dnscache))
601
					continue;
602
			}
603

    
604
			if (is_subnet($rtent['network']))
605
				$ips = array($rtent['network']);
606
			else {
607
				if (!isset($rtent['disabled']))
608
					$filterdns_list[] = $rtent['network'];
609
				$ips = add_hostname_to_watch($rtent['network']);
610
			}
611

    
612
			foreach ($dnscache as $ip) {
613
				if (in_array($ip, $ips))
614
					continue;
615
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
616
				if (isset($config['system']['route-debug'])) {
617
					$mt = microtime();
618
					log_error("ROUTING debug: $mt - route delete $ip ");
619
				}
620
			}
621

    
622
			if (isset($rtent['disabled'])) {
623
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
624
				foreach ($ips as $ip) {
625
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
626
					if (isset($config['system']['route-debug'])) {
627
						$mt = microtime();
628
						log_error("ROUTING debug: $mt - route delete $ip ");
629
					}
630
				}
631
				continue;
632
			}
633

    
634
			foreach ($ips as $ip) {
635
				if (is_ipaddrv4($ip))
636
					$ip .= "/32";
637
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
638
					
639
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
640

    
641
				$cmd = "/sbin/route change {$inet} {$blackhole} " . escapeshellarg($ip) . " ";
642

    
643
				if (is_subnet($ip))
644
					if (is_ipaddr($gatewayip)) {
645
						mwexec($cmd . escapeshellarg($gatewayip));
646
						if (isset($config['system']['route-debug'])) {
647
							$mt = microtime();
648
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
649
						}
650
					} else if (!empty($interfacegw)) {
651
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
652
						if (isset($config['system']['route-debug'])) {
653
							$mt = microtime();
654
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
655
						}
656
					}
657
			}
658
		}
659
		unset($gateways_arr);
660
	}
661
	unset($static_routes);
662

    
663
	if ($update_dns === false) {
664
		if (count($filterdns_list)) {
665
			$interval = 60;
666
			$hostnames = "";
667
			array_unique($filterdns_list);
668
			foreach ($filterdns_list as $hostname)
669
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
670
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
671
			unset($hostnames);
672

    
673
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid"))
674
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
675
			else
676
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
677
		} else {
678
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
679
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
680
		}
681
	}
682
	unset($filterdns_list);
683

    
684
	return 0;
685
}
686

    
687
function system_routing_enable() {
688
	global $config, $g;
689
	if(isset($config['system']['developerspew'])) {
690
		$mt = microtime();
691
		echo "system_routing_enable() being called $mt\n";
692
	}
693

    
694
	set_sysctl(array(
695
		"net.inet.ip.forwarding" => "1",
696
		"net.inet6.ip6.forwarding" => "1"
697
	));
698

    
699
	return;
700
}
701

    
702
function system_syslogd_fixup_server($server) {
703
	/* If it's an IPv6 IP alone, encase it in brackets */
704
	if (is_ipaddrv6($server))
705
		return "[$server]";
706
	else
707
		return $server;
708
}
709

    
710
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
711
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
712
	$facility .= " ".
713
	$remote_servers = "";
714
	$pad_to  = 56;
715
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
716
	if($syslogcfg['remoteserver'])
717
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
718
	if($syslogcfg['remoteserver2'])
719
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
720
	if($syslogcfg['remoteserver3'])
721
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
722
	return $remote_servers;
723
}
724

    
725
function system_syslogd_start() {
726
	global $config, $g;
727
	if(isset($config['system']['developerspew'])) {
728
		$mt = microtime();
729
		echo "system_syslogd_start() being called $mt\n";
730
	}
731

    
732
	mwexec("/etc/rc.d/hostid start");
733

    
734
	$syslogcfg = $config['syslog'];
735

    
736
	if (platform_booting())
737
		echo gettext("Starting syslog...");
738

    
739
	if (is_process_running("fifolog_writer"))
740
		mwexec('/bin/pkill fifolog_writer');
741

    
742
	// Which logging type are we using this week??
743
	if (isset($config['system']['disablesyslogclog'])) {
744
		$log_directive = "";
745
		$log_create_directive = "/usr/bin/touch ";
746
		$log_size = "";
747
	} else if (isset($config['system']['usefifolog'])) {
748
		$log_directive = "|/usr/sbin/fifolog_writer ";
749
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
750
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
751
	} else { // Defaults to CLOG
752
		$log_directive = "%";
753
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
754
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
755
	}
756

    
757
	$syslogd_extra = "";
758
	if (isset($syslogcfg)) {
759
		$separatelogfacilities = array('ntp','ntpd','ntpdate','charon','ipsec_starter','openvpn','pptps','poes','l2tps','relayd','hostapd','dnsmasq','filterdns','unbound','dhcpd','dhcrelay','dhclient','dhcp6c','apinger','radvd','routed','olsrd','zebra','ospfd','bgpd','miniupnpd','filterlog');
760
		$syslogconf = "";
761
		if($config['installedpackages']['package']) {
762
			foreach($config['installedpackages']['package'] as $package) {
763
				if($package['logging']) {
764
					array_push($separatelogfacilities, $package['logging']['facilityname']);
765
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename']))
766
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
767
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
768
				}
769
			}
770
		}
771
		$facilitylist = implode(',', array_unique($separatelogfacilities));
772
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
773
		if (!isset($syslogcfg['disablelocallogging']))
774
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
775

    
776
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
777
		if (!isset($syslogcfg['disablelocallogging'])) 
778
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
779

    
780
		$syslogconf .= "!ppp\n";
781
		if (!isset($syslogcfg['disablelocallogging'])) 
782
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
783

    
784
		$syslogconf .= "!pptps\n";
785
		if (!isset($syslogcfg['disablelocallogging'])) 
786
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
787

    
788
		$syslogconf .= "!poes\n";
789
		if (!isset($syslogcfg['disablelocallogging'])) 
790
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
791

    
792
		$syslogconf .= "!l2tps\n";
793
		if (!isset($syslogcfg['disablelocallogging'])) 
794
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
795

    
796
		$syslogconf .= "!charon,ipsec_starter\n";
797
		if (!isset($syslogcfg['disablelocallogging'])) 
798
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
799
		if (isset($syslogcfg['vpn']))
800
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
801

    
802
		$syslogconf .= "!openvpn\n";
803
		if (!isset($syslogcfg['disablelocallogging'])) 
804
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
805
		if (isset($syslogcfg['vpn']))
806
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
807

    
808
		$syslogconf .= "!apinger\n";
809
		if (!isset($syslogcfg['disablelocallogging']))
810
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
811
		if (isset($syslogcfg['apinger']))
812
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
813

    
814
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
815
		if (!isset($syslogcfg['disablelocallogging']))
816
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
817

    
818
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
819
		if (!isset($syslogcfg['disablelocallogging']))
820
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
821
		if (isset($syslogcfg['dhcp']))
822
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
823

    
824
		$syslogconf .= "!relayd\n";
825
		if (!isset($syslogcfg['disablelocallogging']))
826
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
827
		if (isset($syslogcfg['relayd']))
828
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
829

    
830
		$syslogconf .= "!hostapd\n";
831
		if (!isset($syslogcfg['disablelocallogging']))
832
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
833
		if (isset($syslogcfg['hostapd']))
834
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
835

    
836
		$syslogconf .= "!filterlog\n";
837
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
838
		if (isset($syslogcfg['filter']))
839
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
840

    
841
		$syslogconf .= "!-{$facilitylist}\n";
842
		if (!isset($syslogcfg['disablelocallogging'])) 
843
			$syslogconf .= <<<EOD
844
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
845
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
846
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
847
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
848
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
849
local7.none							{$log_directive}{$g['varlog_path']}/system.log
850
security.*							{$log_directive}{$g['varlog_path']}/system.log
851
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
852
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
853
*.emerg								*
854

    
855
EOD;
856
		if (isset($syslogcfg['vpn']))
857
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
858
		if (isset($syslogcfg['portalauth']))
859
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
860
		if (isset($syslogcfg['dhcp']))
861
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
862
		if (isset($syslogcfg['system'])) {
863
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
864
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
865
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
866
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
867
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
868
		}
869
		if (isset($syslogcfg['logall'])) {
870
			// Make everything mean everything, including facilities excluded above.
871
			$syslogconf .= "!*\n";
872
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
873
		}
874

    
875
		if (isset($syslogcfg['zmqserver'])) {
876
				$syslogconf .= <<<EOD
877
*.*								^{$syslogcfg['zmqserver']}
878

    
879
EOD;
880
		}
881
		/* write syslog.conf */		
882
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
883
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
884
			unset($syslogconf);
885
			return 1;
886
		}
887
		unset($syslogconf);
888

    
889
		// Ensure that the log directory exists
890
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run"))
891
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
892

    
893
		$sourceip = "";
894
		if (!empty($syslogcfg['sourceip'])) {
895
			if ($syslogcfg['ipproto'] == "ipv6") {
896
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
897
				if (!is_ipaddr($ifaddr))
898
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
899
			} else {
900
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
901
				if (!is_ipaddr($ifaddr))
902
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
903
			}
904
			if (is_ipaddr($ifaddr)) {
905
				$sourceip = "-b {$ifaddr}";
906
			}
907
		}
908

    
909
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
910
	}
911

    
912
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
913
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
914
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
915
	}
916
	
917
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
918
		// if it still hasn't responded to the TERM, KILL it. 
919
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
920
		usleep(100000); 
921
	}
922

    
923
	
924
	$retval = mwexec_bg("/usr/sbin/syslogd -s -c -c -l {$g['dhcpd_chroot_path']}/var/run/log -P {$g['varrun_path']}/syslog.pid {$syslogd_extra}");
925

    
926
	if (platform_booting())
927
		echo gettext("done.") . "\n";
928

    
929
	return $retval;
930
}
931

    
932
function system_webgui_create_certificate() {
933
	global $config, $g;
934

    
935
	if (!is_array($config['ca']))
936
		$config['ca'] = array();
937
	$a_ca =& $config['ca'];
938
	if (!is_array($config['cert']))
939
		$config['cert'] = array();
940
	$a_cert =& $config['cert'];
941
	log_error("Creating SSL Certificate for this host");
942

    
943
	$cert = array();
944
	$cert['refid'] = uniqid();
945
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
946

    
947
	$dn = array(
948
		'countryName' => "US",
949
		'stateOrProvinceName' => "State",
950
		'localityName' => "Locality",
951
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
952
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
953
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
954
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
955
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")){
956
		while($ssl_err = openssl_error_string()){
957
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
958
		}
959
		error_reporting($old_err_level);
960
		return null;
961
	}
962
	error_reporting($old_err_level);
963

    
964
	$a_cert[] = $cert;
965
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
966
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
967
	return $cert;
968
}
969

    
970
function system_webgui_start() {
971
	global $config, $g;
972

    
973
	if (platform_booting())
974
		echo gettext("Starting webConfigurator...");
975

    
976
	chdir($g['www_path']);
977

    
978
	/* defaults */
979
	$portarg = "80";
980
	$crt = "";
981
	$key = "";
982
	$ca = "";
983

    
984
	/* non-standard port? */
985
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "")
986
		$portarg = "{$config['system']['webgui']['port']}";
987

    
988
	if ($config['system']['webgui']['protocol'] == "https") {
989
		// Ensure that we have a webConfigurator CERT
990
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
991
		if(!is_array($cert) || !$cert['crt'] || !$cert['prv'])
992
			$cert = system_webgui_create_certificate();
993
		$crt = base64_decode($cert['crt']);
994
		$key = base64_decode($cert['prv']);
995

    
996
		if(!$config['system']['webgui']['port'])
997
			$portarg = "443";
998
		$ca  = ca_chain($cert);
999
	}
1000

    
1001
	/* generate lighttpd configuration */
1002
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
1003
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
1004
		"cert.pem", "ca.pem");
1005

    
1006
	/* kill any running lighttpd */
1007
	killbypid("{$g['varrun_path']}/lighty-webConfigurator.pid");
1008

    
1009
	sleep(1);
1010

    
1011
	@unlink("{$g['varrun_path']}/lighty-webConfigurator.pid");
1012

    
1013
	/* attempt to start lighthttpd */
1014
	$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-webConfigurator.conf");
1015

    
1016
	if (platform_booting()) {
1017
		if ($res == 0)
1018
			echo gettext("done.") . "\n";
1019
		else
1020
			echo gettext("failed!") . "\n";
1021
	}
1022

    
1023
	return $res;
1024
}
1025

    
1026
function system_generate_lighty_config($filename,
1027
	$cert,
1028
	$key,
1029
	$ca,
1030
	$pid_file,
1031
	$port = 80,
1032
	$document_root = "/usr/local/www/",
1033
	$cert_location = "cert.pem",
1034
	$ca_location = "ca.pem",
1035
	$captive_portal = false) {
1036

    
1037
	global $config, $g;
1038

    
1039
	if(!is_dir("{$g['tmp_path']}/lighttpdcompress"))
1040
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1041

    
1042
	if(isset($config['system']['developerspew'])) {
1043
		$mt = microtime();
1044
		echo "system_generate_lighty_config() being called $mt\n";
1045
	}
1046

    
1047
	if ($captive_portal !== false)  {
1048
		$captiveportal = ",\"mod_rewrite\",\"mod_evasive\"";
1049
		$captive_portal_rewrite = "url.rewrite-once = ( \"(.*captiveportal.*)\" => \"$1\", \"(.*)\" => \"/index.php?zone={$captive_portal}&redirurl=$1\" )\n";
1050

    
1051
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1052
		if (empty($maxprocperip))
1053
			$maxprocperip = 10;
1054
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
1055

    
1056
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
1057
		if(!is_dir("{$g['tmp_path']}/captiveportal"))
1058
			@mkdir("{$g['tmp_path']}/captiveportal", 0555);
1059
		$server_max_request_size = "server.max-request-size    = 384";
1060
		$cgi_config = "";
1061
	} else {
1062
		$captiveportal = ",\"mod_cgi\"";
1063
		$captive_portal_rewrite = "";
1064
		$captive_portal_mod_evasive = "";
1065
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
1066
		$server_max_request_size = "server.max-request-size    = 2097152";
1067
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
1068
	}
1069
	
1070
	if (empty($port))
1071
		$lighty_port = "80";
1072
	else
1073
		$lighty_port = $port;
1074

    
1075
	$memory = get_memory();
1076
	$realmem = $memory[1];
1077

    
1078
	// Determine web GUI process settings and take into account low memory systems
1079
	if ($realmem < 255)
1080
		$max_procs = 1;
1081
	else
1082
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1083

    
1084
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM 
1085
	if ($captive_portal !== false)  {
1086
		if ($realmem > 135 and $realmem < 256) {
1087
			$max_procs += 1; // 2 worker processes
1088
		} else if ($realmem > 255 and $realmem < 513) {
1089
			$max_procs += 2; // 3 worker processes
1090
		} else if ($realmem > 512) {
1091
			$max_procs += 4; // 6 worker processes
1092
		}
1093
		if ($max_procs > 1)
1094
			$max_php_children = intval($max_procs/2);
1095
		else
1096
			$max_php_children = 1;
1097

    
1098
	} else {
1099
		if ($realmem < 78)
1100
			$max_php_children = 0;
1101
		else
1102
			$max_php_children = 1;
1103
	}
1104

    
1105
	if(!isset($config['syslog']['nologlighttpd'])) {
1106
		$lighty_use_syslog = <<<EOD
1107
## where to send error-messages to
1108
server.errorlog-use-syslog="enable"
1109
EOD;
1110
	}
1111

    
1112

    
1113
	if ($captive_portal !== false) {
1114
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
1115
		$fastcgi_config = <<<EOD
1116
#### fastcgi module
1117
## read fastcgi.txt for more info
1118
fastcgi.server = ( ".php" =>
1119
	( "localhost" =>
1120
		(
1121
			"socket" => "{$fast_cgi_path}",
1122
			"max-procs" => {$max_procs},
1123
			"bin-environment" => (
1124
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
1125
				"PHP_FCGI_MAX_REQUESTS" => "500"
1126
			),
1127
			"bin-path" => "/usr/local/bin/php"
1128
		)
1129
	)
1130
)
1131

    
1132
EOD;
1133
	} else {
1134
		$fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
1135
		$fastcgi_config = <<<EOD
1136
#### fastcgi module
1137
## read fastcgi.txt for more info
1138
fastcgi.server = ( ".php" =>
1139
	( "localhost" =>
1140
		(
1141
			"socket" => "{$fast_cgi_path}",
1142
			"broken-scriptfilename" => "enable"
1143
		)
1144
	)
1145
)
1146

    
1147
EOD;
1148
	}
1149

    
1150

    
1151
	$lighty_config = <<<EOD
1152
#
1153
# lighttpd configuration file
1154
#
1155
# use a it as base for lighttpd 1.0.0 and above
1156
#
1157
############ Options you really have to take care of ####################
1158

    
1159
## FreeBSD!
1160
server.event-handler	= "freebsd-kqueue"
1161
server.network-backend 	= "writev"
1162
#server.use-ipv6 = "enable"
1163

    
1164
## modules to load
1165
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1166
	{$captiveportal}, "mod_fastcgi"
1167
)
1168

    
1169
server.max-keep-alive-requests = 15
1170
server.max-keep-alive-idle = 30
1171

    
1172
## a static document-root, for virtual-hosting take look at the
1173
## server.virtual-* options
1174
server.document-root        = "{$document_root}"
1175
{$captive_portal_rewrite}
1176

    
1177
# Maximum idle time with nothing being written (php downloading)
1178
server.max-write-idle = 999
1179

    
1180
{$lighty_use_syslog}
1181

    
1182
# files to check for if .../ is requested
1183
server.indexfiles           = ( "index.php", "index.html",
1184
                                "index.htm", "default.htm" )
1185

    
1186
# mimetype mapping
1187
mimetype.assign             = (
1188
  ".pdf"          =>      "application/pdf",
1189
  ".sig"          =>      "application/pgp-signature",
1190
  ".spl"          =>      "application/futuresplash",
1191
  ".class"        =>      "application/octet-stream",
1192
  ".ps"           =>      "application/postscript",
1193
  ".torrent"      =>      "application/x-bittorrent",
1194
  ".dvi"          =>      "application/x-dvi",
1195
  ".gz"           =>      "application/x-gzip",
1196
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
1197
  ".swf"          =>      "application/x-shockwave-flash",
1198
  ".tar.gz"       =>      "application/x-tgz",
1199
  ".tgz"          =>      "application/x-tgz",
1200
  ".tar"          =>      "application/x-tar",
1201
  ".zip"          =>      "application/zip",
1202
  ".mp3"          =>      "audio/mpeg",
1203
  ".m3u"          =>      "audio/x-mpegurl",
1204
  ".wma"          =>      "audio/x-ms-wma",
1205
  ".wax"          =>      "audio/x-ms-wax",
1206
  ".ogg"          =>      "audio/x-wav",
1207
  ".wav"          =>      "audio/x-wav",
1208
  ".gif"          =>      "image/gif",
1209
  ".jpg"          =>      "image/jpeg",
1210
  ".jpeg"         =>      "image/jpeg",
1211
  ".png"          =>      "image/png",
1212
  ".svg"          =>      "image/svg+xml",
1213
  ".xbm"          =>      "image/x-xbitmap",
1214
  ".xpm"          =>      "image/x-xpixmap",
1215
  ".xwd"          =>      "image/x-xwindowdump",
1216
  ".css"          =>      "text/css",
1217
  ".html"         =>      "text/html",
1218
  ".htm"          =>      "text/html",
1219
  ".js"           =>      "text/javascript",
1220
  ".asc"          =>      "text/plain",
1221
  ".c"            =>      "text/plain",
1222
  ".conf"         =>      "text/plain",
1223
  ".text"         =>      "text/plain",
1224
  ".txt"          =>      "text/plain",
1225
  ".dtd"          =>      "text/xml",
1226
  ".xml"          =>      "text/xml",
1227
  ".mpeg"         =>      "video/mpeg",
1228
  ".mpg"          =>      "video/mpeg",
1229
  ".mov"          =>      "video/quicktime",
1230
  ".qt"           =>      "video/quicktime",
1231
  ".avi"          =>      "video/x-msvideo",
1232
  ".asf"          =>      "video/x-ms-asf",
1233
  ".asx"          =>      "video/x-ms-asf",
1234
  ".wmv"          =>      "video/x-ms-wmv",
1235
  ".bz2"          =>      "application/x-bzip",
1236
  ".tbz"          =>      "application/x-bzip-compressed-tar",
1237
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
1238
 )
1239

    
1240
# Use the "Content-Type" extended attribute to obtain mime type if possible
1241
#mimetypes.use-xattr        = "enable"
1242

    
1243
## deny access the file-extensions
1244
#
1245
# ~    is for backupfiles from vi, emacs, joe, ...
1246
# .inc is often used for code includes which should in general not be part
1247
#      of the document-root
1248
url.access-deny             = ( "~", ".inc" )
1249

    
1250

    
1251
######### Options that are good to be but not necessary to be changed #######
1252

    
1253
## bind to port (default: 80)
1254

    
1255
EOD;
1256

    
1257
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1258
	$lighty_config .= "server.port  = {$lighty_port}\n";
1259
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1260
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1261
	if($cert <> "" and $key <> "") {
1262
		$lighty_config .= "\n";
1263
		$lighty_config .= "## ssl configuration\n";
1264
		$lighty_config .= "ssl.engine = \"enable\"\n";
1265
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1266
		if($ca <> "")
1267
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1268
	}
1269
	$lighty_config .= " }\n";
1270

    
1271

    
1272
	$lighty_config .= <<<EOD
1273

    
1274
## error-handler for status 404
1275
#server.error-handler-404   = "/error-handler.html"
1276
#server.error-handler-404   = "/error-handler.php"
1277

    
1278
## to help the rc.scripts
1279
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1280

    
1281
## virtual directory listings
1282
server.dir-listing         = "disable"
1283

    
1284
## enable debugging
1285
debug.log-request-header   = "disable"
1286
debug.log-response-header  = "disable"
1287
debug.log-request-handling = "disable"
1288
debug.log-file-not-found   = "disable"
1289

    
1290
# gzip compression
1291
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1292
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1293

    
1294
{$server_upload_dirs}
1295

    
1296
{$server_max_request_size}
1297

    
1298
{$fastcgi_config}
1299

    
1300
{$cgi_config}
1301

    
1302
{$captive_portal_mod_evasive}
1303

    
1304
expire.url = (
1305
				"" => "access 50 hours",	
1306
        )
1307

    
1308
EOD;
1309

    
1310
	$cert = str_replace("\r", "", $cert);
1311
	$key = str_replace("\r", "", $key);
1312
	$ca = str_replace("\r", "", $ca);
1313

    
1314
	$cert = str_replace("\n\n", "\n", $cert);
1315
	$key = str_replace("\n\n", "\n", $key);
1316
	$ca = str_replace("\n\n", "\n", $ca);
1317

    
1318
	if($cert <> "" and $key <> "") {
1319
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1320
		if (!$fd) {
1321
			printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
1322
			return 1;
1323
		}
1324
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1325
		fwrite($fd, $cert);
1326
		fwrite($fd, "\n");
1327
		fwrite($fd, $key);
1328
		fclose($fd);
1329
		if(!(empty($ca) || (strlen(trim($ca)) == 0))) {
1330
			$fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
1331
			if (!$fd) {
1332
				printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
1333
				return 1;
1334
			}
1335
			chmod("{$g['varetc_path']}/{$ca_location}", 0600);
1336
			fwrite($fd, $ca);
1337
			fclose($fd);
1338
		}
1339
		$lighty_config .= "\n";
1340
		$lighty_config .= "## " . gettext("ssl configuration") . "\n";
1341
		$lighty_config .= "ssl.engine = \"enable\"\n";
1342
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1343

    
1344
		// SSLv2/3 is deprecated, force use of TLS
1345
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1346
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1347

    
1348
		// where ssl.cipher-list is set, this is automatically enabled, but set it explicitly anyway.
1349
		$lighty_config .= "ssl.honor-cipher-order = \"enable\"\n";
1350

    
1351
		$lighty_config .= "ssl.cipher-list = \"AES128+EECDH:AES256+EECDH:AES128+EDH:AES256+EDH:AES128-SHA:AES256-SHA:!aNULL:!eNULL:!DSS\"\n";
1352

    
1353
		if(!(empty($ca) || (strlen(trim($ca)) == 0)))
1354
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1355
	}
1356

    
1357
	// Add HTTP to HTTPS redirect	
1358
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1359
		if($lighty_port != "443") 
1360
			$redirectport = ":{$lighty_port}";
1361
		$lighty_config .= <<<EOD
1362
\$SERVER["socket"] == ":80" {
1363
	\$HTTP["host"] =~ "(.*)" {
1364
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1365
	}
1366
}
1367
\$SERVER["socket"] == "[::]:80" {
1368
	\$HTTP["host"] =~ "(.*)" {
1369
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1370
	}
1371
}
1372
EOD;
1373
	}
1374

    
1375
	$fd = fopen("{$filename}", "w");
1376
	if (!$fd) {
1377
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1378
		return 1;
1379
	}
1380
	fwrite($fd, $lighty_config);
1381
	fclose($fd);
1382

    
1383
	return 0;
1384

    
1385
}
1386

    
1387
function system_timezone_configure() {
1388
	global $config, $g;
1389
	if(isset($config['system']['developerspew'])) {
1390
		$mt = microtime();
1391
		echo "system_timezone_configure() being called $mt\n";
1392
	}
1393

    
1394
	$syscfg = $config['system'];
1395

    
1396
	if (platform_booting())
1397
		echo gettext("Setting timezone...");
1398

    
1399
	/* extract appropriate timezone file */
1400
	$timezone = $syscfg['timezone'];
1401
	if ($timezone) {
1402
		exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
1403
		foreach ($tzs as $tz) {
1404
			if (preg_match(",{$timezone}$,", $tz))
1405
				break;
1406
			if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
1407
				$timezone = $matches[1];
1408
				break;
1409
			}
1410
		}
1411
	} else
1412
		$timezone = "Etc/UTC";
1413

    
1414
	conf_mount_rw();
1415

    
1416
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1417
		escapeshellarg($timezone) . " > /etc/localtime");
1418

    
1419
	mwexec("sync");
1420
	conf_mount_ro();
1421

    
1422
	if (platform_booting())
1423
		echo gettext("done.") . "\n";
1424
}
1425

    
1426
function system_ntp_setup_gps($serialport) {
1427
	global $config, $g;
1428
	$gps_device = '/dev/gps0';
1429
	$serialport = '/dev/'.$serialport;
1430

    
1431
	if (!file_exists($serialport))
1432
		return false;
1433

    
1434
	conf_mount_rw();
1435
	// Create symlink that ntpd requires
1436
	unlink_if_exists($gps_device);
1437
	@symlink($serialport, $gps_device);
1438

    
1439
	$gpsbaud = '4800';
1440
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1441
		switch ($config['ntpd']['gps']['speed']) {
1442
			case '16':
1443
				$gpsbaud = '9600';
1444
				break;
1445
			case '32':
1446
				$gpsbaud = '19200';
1447
				break;
1448
			case '48':
1449
				$gpsbaud = '38400';
1450
				break;
1451
			case '64':
1452
				$gpsbaud = '57600';
1453
				break;
1454
			case '80':
1455
				$gpsbaud = '115200';
1456
				break;
1457
		}
1458
	}
1459

    
1460
	/* Configure the serial port for raw IO and set the speed */
1461
	mwexec("stty -f {$serialport}.init raw speed {$gpsbaud}");
1462

    
1463
	/* Send the following to the GPS port to initialize the GPS */
1464
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1465
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1466
	}else{
1467
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1468
	}
1469

    
1470
	/* XXX: Why not file_put_contents to the device */
1471
	@file_put_contents('/tmp/gps.init', $gps_init);
1472
	mwexec("cat /tmp/gps.init > {$serialport}");
1473

    
1474
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1475
	if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
1476
		@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:", FILE_APPEND);
1477
	}
1478

    
1479
	conf_mount_ro();
1480

    
1481
	return true;
1482
}
1483

    
1484
function system_ntp_setup_pps($serialport) {
1485
	global $config, $g;
1486

    
1487
	$pps_device = '/dev/pps0';
1488
	$serialport = '/dev/'.$serialport;
1489

    
1490
	if (!file_exists($serialport))
1491
		return false;
1492

    
1493
	conf_mount_rw();
1494
	// Create symlink that ntpd requires
1495
	unlink_if_exists($pps_device);
1496
	@symlink($serialport, $pps_device);
1497

    
1498
	conf_mount_ro();
1499

    
1500
	return true;
1501
}
1502

    
1503

    
1504
function system_ntp_configure($start_ntpd=true) {
1505
	global $config, $g;
1506

    
1507
	$driftfile = "/var/db/ntpd.drift";
1508
	$statsdir = "/var/log/ntp";
1509
	$gps_device = '/dev/gps0';
1510

    
1511
	if ($g['platform'] == 'jail')
1512
		return;
1513

    
1514
	safe_mkdir($statsdir);
1515

    
1516
	if (!is_array($config['ntpd']))
1517
		$config['ntpd'] = array();
1518

    
1519
	$ntpcfg = "# \n";
1520
	$ntpcfg .= "# pfSense ntp configuration file \n";
1521
	$ntpcfg .= "# \n\n";
1522
	$ntpcfg .= "tinker panic 0 \n";
1523

    
1524
	/* Add Orphan mode */
1525
	$ntpcfg .= "# Orphan mode stratum\n";
1526
	$ntpcfg .= 'tos orphan ';
1527
	if (!empty($config['ntpd']['orphan'])) {
1528
		$ntpcfg .= $config['ntpd']['orphan'];
1529
	}else{
1530
		$ntpcfg .= '12';
1531
	}
1532
	$ntpcfg .= "\n";
1533

    
1534
	/* Add PPS configuration */
1535
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port'])
1536
		&& file_exists('/dev/'.$config['ntpd']['pps']['port'])
1537
		&& system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1538
		$ntpcfg .= "\n";
1539
		$ntpcfg .= "# PPS Setup\n";
1540
		$ntpcfg .= 'server 127.127.22.0';
1541
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1542
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1543
			$ntpcfg .= ' prefer'; 
1544
		}
1545
		if (!empty($config['ntpd']['pps']['noselect'])) {
1546
			$ntpcfg .= ' noselect ';
1547
		}
1548
		$ntpcfg .= "\n";
1549
		$ntpcfg .= 'fudge 127.127.22.0';
1550
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1551
			$ntpcfg .= ' time1 ';
1552
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1553
		}
1554
		if (!empty($config['ntpd']['pps']['flag2'])) {
1555
			$ntpcfg .= ' flag2 1';
1556
		}
1557
		if (!empty($config['ntpd']['pps']['flag3'])) {
1558
			$ntpcfg .= ' flag3 1';
1559
		}else{
1560
			$ntpcfg .= ' flag3 0';
1561
		}
1562
		if (!empty($config['ntpd']['pps']['flag4'])) {
1563
			$ntpcfg .= ' flag4 1';
1564
		}
1565
		if (!empty($config['ntpd']['pps']['refid'])) {
1566
			$ntpcfg .= ' refid ';
1567
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1568
		}
1569
		$ntpcfg .= "\n";
1570
	}
1571
	/* End PPS configuration */
1572

    
1573
	/* Add GPS configuration */
1574
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port'])
1575
		&& file_exists('/dev/'.$config['ntpd']['gps']['port'])
1576
		&& system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1577
		$ntpcfg .= "\n";
1578
		$ntpcfg .= "# GPS Setup\n";
1579
		$ntpcfg .= 'server 127.127.20.0 mode ';
1580
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1581
			if (!empty($config['ntpd']['gps']['nmea'])) {
1582
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1583
			}
1584
			if (!empty($config['ntpd']['gps']['speed'])) {
1585
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1586
			}
1587
			if (!empty($config['ntpd']['gps']['subsec'])) {
1588
				$ntpmode += 128;
1589
			}
1590
			$ntpcfg .= (string) $ntpmode;
1591
		}else{
1592
			$ntpcfg .= '0';
1593
		}
1594
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1595
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1596
			$ntpcfg .= ' prefer'; 
1597
		}
1598
		if (!empty($config['ntpd']['gps']['noselect'])) {
1599
			$ntpcfg .= ' noselect ';
1600
		}
1601
		$ntpcfg .= "\n";
1602
		$ntpcfg .= 'fudge 127.127.20.0';
1603
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1604
			$ntpcfg .= ' time1 ';
1605
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1606
		}
1607
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1608
			$ntpcfg .= ' time2 ';
1609
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1610
		}
1611
		if (!empty($config['ntpd']['gps']['flag1'])) {
1612
			$ntpcfg .= ' flag1 1';
1613
		}else{
1614
			$ntpcfg .= ' flag1 0';
1615
		}
1616
		if (!empty($config['ntpd']['gps']['flag2'])) {
1617
			$ntpcfg .= ' flag2 1';
1618
		}
1619
		if (!empty($config['ntpd']['gps']['flag3'])) {
1620
			$ntpcfg .= ' flag3 1';
1621
		}else{
1622
			$ntpcfg .= ' flag3 0';
1623
		}
1624
		if (!empty($config['ntpd']['gps']['flag4'])) {
1625
			$ntpcfg .= ' flag4 1';
1626
		}
1627
		if (!empty($config['ntpd']['gps']['refid'])) {
1628
			$ntpcfg .= ' refid ';
1629
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1630
		}
1631
		$ntpcfg .= "\n";
1632
	}elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport'])
1633
		&& file_exists('/dev/'.$config['ntpd']['gpsport'])
1634
		&& system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1635
		/* This handles a 2.1 and earlier config */
1636
		$ntpcfg .= "# GPS Setup\n";
1637
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1638
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1639
		// Fall back to local clock if GPS is out of sync?
1640
		$ntpcfg .= "server 127.127.1.0\n";
1641
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1642
	}
1643
	/* End GPS configuration */
1644
	
1645
	$ntpcfg .= "\n\n# Upstream Servers\n";
1646
	/* foreach through ntp servers and write out to ntpd.conf */
1647
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1648
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1649
		if (substr_count($config['ntpd']['prefer'], $ts)) $ntpcfg .= ' prefer';
1650
		if (substr_count($config['ntpd']['noselect'], $ts)) $ntpcfg .= ' noselect';
1651
		$ntpcfg .= "\n";
1652
	}
1653
	unset($ts);
1654

    
1655
	$ntpcfg .= "\n\n";
1656
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1657
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1658
		$ntpcfg .= "enable stats\n";
1659
		$ntpcfg .= 'statistics';
1660
		if (!empty($config['ntpd']['clockstats'])) {
1661
			$ntpcfg .= ' clockstats';
1662
		}
1663
		if (!empty($config['ntpd']['loopstats'])) {
1664
			$ntpcfg .= ' loopstats';
1665
		}
1666
		if (!empty($config['ntpd']['peerstats'])) {
1667
			$ntpcfg .= ' peerstats';
1668
		}
1669
		$ntpcfg .= "\n";
1670
	}
1671
	$ntpcfg .= "statsdir {$statsdir}\n";
1672
	$ntpcfg .= 'logconfig =syncall +clockall';
1673
	if (!empty($config['ntpd']['logpeer'])) {
1674
		$ntpcfg .= ' +peerall';
1675
	}
1676
	if (!empty($config['ntpd']['logsys'])) {
1677
		$ntpcfg .= ' +sysall';
1678
	}
1679
	$ntpcfg .= "\n";
1680
	$ntpcfg .= "driftfile {$driftfile}\n";
1681
	/* Access restrictions */
1682
	$ntpcfg .= 'restrict default';
1683
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1684
		$ntpcfg .= ' kod limited'; 
1685
	}
1686
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1687
		$ntpcfg .= ' nomodify'; 
1688
	}
1689
	if (!empty($config['ntpd']['noquery'])) {
1690
		$ntpcfg .= ' noquery';
1691
	}
1692
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1693
		$ntpcfg .= ' nopeer'; 
1694
	}
1695
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1696
		$ntpcfg .= ' notrap'; 
1697
	}
1698
	if (!empty($config['ntpd']['noserve'])) {
1699
		$ntpcfg .= ' noserve';
1700
	}
1701
	$ntpcfg .= "\nrestrict -6 default";
1702
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1703
		$ntpcfg .= ' kod limited'; 
1704
	}
1705
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1706
		$ntpcfg .= ' nomodify'; 
1707
	}
1708
	if (!empty($config['ntpd']['noquery'])) {
1709
		$ntpcfg .= ' noquery';
1710
	}
1711
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1712
		$ntpcfg .= ' nopeer'; 
1713
	}
1714
	if (!empty($config['ntpd']['noserve'])) {
1715
		$ntpcfg .= ' noserve';
1716
	}
1717
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1718
		$ntpcfg .= ' notrap'; 
1719
	}
1720
	$ntpcfg .= "\n";
1721

    
1722
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1723
	$ntpcfg .= "\n";
1724
	if (!empty($config['ntpd']['leapsec'])) {
1725
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1726
		file_put_contents('/var/db/leap-seconds', $leapsec);
1727
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1728
	}
1729
	
1730

    
1731
	if (empty($config['ntpd']['interface'])) {
1732
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface']))
1733
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1734
		else
1735
			$interfaces = array();
1736
	} else
1737
		$interfaces = explode(",", $config['ntpd']['interface']);
1738

    
1739
	if (is_array($interfaces) && count($interfaces)) {
1740
		$ntpcfg .= "interface ignore all\n";
1741
		foreach ($interfaces as $interface) {
1742
			if (strstr($interface, "_vip")) {
1743
				$interface = get_configured_carp_interface_list($interface);
1744
			}
1745
			if (!is_ipaddr($interface)) {
1746
				$interface = get_real_interface($interface);
1747
			}
1748
			if (!empty($interface))
1749
				$ntpcfg .= "interface listen {$interface}\n";
1750
		}
1751
	}
1752

    
1753
	/* open configuration for writing or bail */
1754
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1755
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1756
		return;
1757
	}
1758

    
1759
	/* At bootup we just want to write out the config. */
1760
	if (!$start_ntpd)
1761
		return;
1762

    
1763
	/* if ntpd is running, kill it */
1764
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1765
		killbypid("{$g['varrun_path']}/ntpd.pid");
1766
	}
1767
	@unlink("{$g['varrun_path']}/ntpd.pid");
1768

    
1769
	/* if /var/empty does not exist, create it */
1770
	if(!is_dir("/var/empty"))
1771
		mkdir("/var/empty", 0775, true);
1772

    
1773
	/* start opentpd, set time now and use /var/etc/ntpd.conf */
1774
	mwexec("/usr/local/sbin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
1775
	
1776
	// Note that we are starting up
1777
	log_error("NTPD is starting up.");
1778
	return;
1779
}
1780

    
1781
function sync_system_time() {
1782
	global $config, $g;
1783

    
1784
	if (platform_booting())
1785
		echo gettext("Syncing system time before startup...");
1786

    
1787
	/* foreach through servers and write out to ntpd.conf */
1788
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1789
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1790
	}
1791
	
1792
	if (platform_booting())
1793
		echo gettext("done.") . "\n";
1794
	
1795
}
1796

    
1797
function system_halt() {
1798
	global $g;
1799

    
1800
	system_reboot_cleanup();
1801

    
1802
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1803
}
1804

    
1805
function system_reboot() {
1806
	global $g;
1807

    
1808
	system_reboot_cleanup();
1809

    
1810
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1811
}
1812

    
1813
function system_reboot_sync() {
1814
	global $g;
1815

    
1816
	system_reboot_cleanup();
1817

    
1818
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1819
}
1820

    
1821
function system_reboot_cleanup() {
1822
	global $config, $cpzone;
1823

    
1824
	mwexec("/usr/local/bin/beep.sh stop");
1825
	require_once("captiveportal.inc");
1826
	if (is_array($config['captiveportal'])) {
1827
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1828
			captiveportal_radius_stop_all();
1829
			captiveportal_send_server_accounting(true);
1830
		}
1831
	}
1832
	require_once("voucher.inc");
1833
	voucher_save_db_to_config();
1834
	require_once("pkg-utils.inc");
1835
	stop_packages();
1836
}
1837

    
1838
function system_do_shell_commands($early = 0) {
1839
	global $config, $g;
1840
	if(isset($config['system']['developerspew'])) {
1841
		$mt = microtime();
1842
		echo "system_do_shell_commands() being called $mt\n";
1843
	}
1844

    
1845
	if ($early)
1846
		$cmdn = "earlyshellcmd";
1847
	else
1848
		$cmdn = "shellcmd";
1849

    
1850
	if (is_array($config['system'][$cmdn])) {
1851

    
1852
		/* *cmd is an array, loop through */
1853
		foreach ($config['system'][$cmdn] as $cmd) {
1854
			exec($cmd);
1855
		}
1856

    
1857
	} elseif($config['system'][$cmdn] <> "") {
1858

    
1859
		/* execute single item */
1860
		exec($config['system'][$cmdn]);
1861

    
1862
	}
1863
}
1864

    
1865
function system_console_configure() {
1866
	global $config, $g;
1867
	if(isset($config['system']['developerspew'])) {
1868
		$mt = microtime();
1869
		echo "system_console_configure() being called $mt\n";
1870
	}
1871

    
1872
	if (isset($config['system']['disableconsolemenu'])) {
1873
		touch("{$g['varetc_path']}/disableconsole");
1874
	} else {
1875
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1876
	}
1877
}
1878

    
1879
function system_dmesg_save() {
1880
	global $g;
1881
	if(isset($config['system']['developerspew'])) {
1882
		$mt = microtime();
1883
		echo "system_dmesg_save() being called $mt\n";
1884
	}
1885

    
1886
	$dmesg = "";
1887
	$_gb = exec("/sbin/dmesg", $dmesg);
1888

    
1889
	/* find last copyright line (output from previous boots may be present) */
1890
	$lastcpline = 0;
1891

    
1892
	for ($i = 0; $i < count($dmesg); $i++) {
1893
		if (strstr($dmesg[$i], "Copyright (c) 1992-"))
1894
			$lastcpline = $i;
1895
	}
1896

    
1897
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1898
	if (!$fd) {
1899
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1900
		return 1;
1901
	}
1902

    
1903
	for ($i = $lastcpline; $i < count($dmesg); $i++)
1904
		fwrite($fd, $dmesg[$i] . "\n");
1905

    
1906
	fclose($fd);
1907
	unset($dmesg);
1908

    
1909
	return 0;
1910
}
1911

    
1912
function system_set_harddisk_standby() {
1913
	global $g, $config;
1914
	if(isset($config['system']['developerspew'])) {
1915
		$mt = microtime();
1916
		echo "system_set_harddisk_standby() being called $mt\n";
1917
	}
1918

    
1919
	if (isset($config['system']['harddiskstandby'])) {
1920
		if (platform_booting()) {
1921
			echo gettext('Setting hard disk standby... ');
1922
		}
1923

    
1924
		$standby = $config['system']['harddiskstandby'];
1925
		// Check for a numeric value
1926
		if (is_numeric($standby)) {
1927
			// Sync the disk(s)
1928
			pfSense_sync();
1929
			if (set_single_sysctl('hw.ata.standby', (int)$standby)) {
1930
				// Reinitialize ATA-drives
1931
				mwexec('/usr/local/sbin/atareinit');
1932
				if (platform_booting()) {
1933
					echo gettext("done.") . "\n";
1934
				}
1935
			} else if (platform_booting()) {
1936
				echo gettext("failed!") . "\n";
1937
			}
1938
		} else if (platform_booting()) {
1939
			echo gettext("failed!") . "\n";
1940
		}
1941
	}
1942
}
1943

    
1944
function system_setup_sysctl() {
1945
	global $config;
1946
	if(isset($config['system']['developerspew'])) {
1947
		$mt = microtime();
1948
		echo "system_setup_sysctl() being called $mt\n";
1949
	}
1950

    
1951
	activate_sysctls();	
1952

    
1953
	if (isset($config['system']['sharednet'])) {
1954
		system_disable_arp_wrong_if();
1955
	}
1956
}
1957

    
1958
function system_disable_arp_wrong_if() {
1959
	global $config;
1960
	if(isset($config['system']['developerspew'])) {
1961
		$mt = microtime();
1962
		echo "system_disable_arp_wrong_if() being called $mt\n";
1963
	}
1964
	set_sysctl(array(
1965
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
1966
		"net.link.ether.inet.log_arp_movements" => "0"
1967
	));
1968
}
1969

    
1970
function system_enable_arp_wrong_if() {
1971
	global $config;
1972
	if(isset($config['system']['developerspew'])) {
1973
		$mt = microtime();
1974
		echo "system_enable_arp_wrong_if() being called $mt\n";
1975
	}
1976
	set_sysctl(array(
1977
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
1978
		"net.link.ether.inet.log_arp_movements" => "1"
1979
	));
1980
}
1981

    
1982
function enable_watchdog() {
1983
	global $config;
1984
	return;
1985
	$install_watchdog = false;
1986
	$supported_watchdogs = array("Geode");
1987
	$file = file_get_contents("/var/log/dmesg.boot");
1988
	foreach($supported_watchdogs as $sd) {
1989
		if(stristr($file, "Geode")) {
1990
			$install_watchdog = true;
1991
		}
1992
	}
1993
	if($install_watchdog == true) {
1994
		if(is_process_running("watchdogd"))
1995
			mwexec("/usr/bin/killall watchdogd", true);
1996
		exec("/usr/sbin/watchdogd");
1997
	}
1998
}
1999

    
2000
function system_check_reset_button() {
2001
	global $g;
2002

    
2003
	$specplatform = system_identify_specific_platform();
2004

    
2005
	switch ($specplatform['name']) {
2006
	case 'alix':
2007
	case 'wrap':
2008
	case 'FW7541':
2009
	case 'APU':
2010
	case 'RCC-VE':
2011
	case 'RCC-DFF':
2012
		break;
2013
	default:
2014
		return 0;
2015
	}
2016

    
2017
	$retval = mwexec("/usr/local/sbin/" . $specplatform['name'] . "resetbtn");
2018

    
2019
	if ($retval == 99) {
2020
		/* user has pressed reset button for 2 seconds - 
2021
		   reset to factory defaults */
2022
		echo <<<EOD
2023

    
2024
***********************************************************************
2025
* Reset button pressed - resetting configuration to factory defaults. *
2026
* The system will reboot after this completes.                        *
2027
***********************************************************************
2028

    
2029

    
2030
EOD;
2031
		
2032
		reset_factory_defaults();
2033
		system_reboot_sync();
2034
		exit(0);
2035
	}
2036

    
2037
	return 0;
2038
}
2039

    
2040
/* attempt to identify the specific platform (for embedded systems)
2041
   Returns an array with two elements:
2042
	name => platform string (e.g. 'wrap', 'alix' etc.)
2043
	descr => human-readable description (e.g. "PC Engines WRAP")
2044
*/
2045
function system_identify_specific_platform() {
2046
	global $g;
2047
	
2048
	if ($g['platform'] == 'generic-pc')
2049
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2050
	
2051
	if ($g['platform'] == 'generic-pc-cdrom')
2052
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2053
	
2054
	/* Try to guess from smbios strings */
2055
	unset($output);
2056
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2057
	switch ($output[0]) {
2058
	case 'FW7541':
2059
		return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2060
		break;
2061
	case 'APU':
2062
		return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2063
		break;
2064
	case 'RCC-VE':
2065
		return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2066
		break;
2067
	case 'DFFv2':
2068
		return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2069
		break;
2070
	case 'SYS-5018A-FTN4':
2071
	case 'A1SAi':
2072
		return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2073
		break;
2074
	case 'SYS-5018D-FN4T':
2075
		return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
2076
		break;
2077
	}
2078

    
2079
	/* the rest of the code only deals with 'embedded' platforms */
2080
	if ($g['platform'] != 'nanobsd')
2081
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2082

    
2083
	$dmesg = get_single_sysctl('hw.model');
2084

    
2085
	if (strpos($dmesg, "PC Engines WRAP") !== false)
2086
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2087
	
2088
	if (strpos($dmesg, "PC Engines ALIX") !== false)
2089
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2090

    
2091
	if (preg_match("/Soekris net45../", $dmesg, $matches))
2092
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2093
	
2094
	if (preg_match("/Soekris net48../", $dmesg, $matches))
2095
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2096
		
2097
	if (preg_match("/Soekris net55../", $dmesg, $matches))
2098
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2099

    
2100
	unset($dmesg);
2101

    
2102
	$dmesg_boot = system_get_dmesg_boot();
2103
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false)
2104
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2105
	unset($dmesg_boot);
2106

    
2107
	/* unknown embedded platform */
2108
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2109
}
2110

    
2111
function system_get_dmesg_boot() {
2112
	global $g;
2113
		
2114
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2115
}
2116

    
2117
function get_possible_listen_ips($include_ipv6_link_local=false) {
2118
	$interfaces = get_configured_interface_with_descr();
2119
	$carplist = get_configured_carp_interface_list();
2120
	$listenips = array();
2121
	foreach ($carplist as $cif => $carpip)
2122
		$interfaces[$cif] = $carpip." (".get_vip_descr($carpip).")";
2123
	$aliaslist = get_configured_ip_aliases_list();
2124
	foreach ($aliaslist as $aliasip => $aliasif)
2125
		$interfaces[$aliasip] = $aliasip." (".get_vip_descr($aliasip).")";
2126
	foreach ($interfaces as $iface => $ifacename) {
2127
		$tmp["name"]  = $ifacename;
2128
		$tmp["value"] = $iface;
2129
		$listenips[] = $tmp;
2130
		if ($include_ipv6_link_local) {
2131
			$llip = find_interface_ipv6_ll(get_real_interface($iface));
2132
			if (!empty($llip)) {
2133
				$tmp["name"]  = "{$ifacename} IPv6 Link-Local";
2134
				$tmp["value"] = $llip;
2135
				$listenips[] = $tmp;
2136
			}
2137
		}
2138
	}
2139
	$tmp["name"]  = "Localhost";
2140
	$tmp["value"] = "lo0";
2141
	$listenips[] = $tmp;
2142
	return $listenips;
2143
}
2144

    
2145
function get_possible_traffic_source_addresses($include_ipv6_link_local=false) {
2146
	global $config;
2147
	$sourceips = get_possible_listen_ips($include_ipv6_link_local);
2148
	foreach (array('server', 'client') as $mode) {
2149
		if (is_array($config['openvpn']["openvpn-{$mode}"])) {
2150
			foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
2151
				if (!isset($setting['disable'])) {
2152
					$vpn = array();
2153
					$vpn['value'] = 'ovpn' . substr($mode, 0, 1) . $setting['vpnid'];
2154
					$vpn['name'] = gettext("OpenVPN") . " ".$mode.": ".htmlspecialchars($setting['description']);
2155
					$sourceips[] = $vpn;
2156
				}
2157
			}
2158
		}
2159
	}
2160
	return $sourceips;
2161
}
2162
?>
(53-53/68)