Project

General

Profile

Download (66.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	system.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
7
	All rights reserved.
8

    
9
	originally part of m0n0wall (http://m0n0.ch/wall)
10
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
	All rights reserved.
12

    
13
	Redistribution and use in source and binary forms, with or without
14
	modification, are permitted provided that the following conditions are met:
15

    
16
	1. Redistributions of source code must retain the above copyright notice,
17
	   this list of conditions and the following disclaimer.
18

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

    
24
	3. All advertising materials mentioning features or use of this software
25
	   must display the following acknowledgment:
26
	   "This product includes software developed by the pfSense Project
27
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
28

    
29
	4. The names "pfSense" and "pfSense Project" must not be used to
30
	   endorse or promote products derived from this software without
31
	   prior written permission. For written permission, please contact
32
	   coreteam@pfsense.org.
33

    
34
	5. Products derived from this software may not be called "pfSense"
35
	   nor may "pfSense" appear in their names without prior written
36
	   permission of the Electric Sheep Fencing, LLC.
37

    
38
	6. Redistributions of any form whatsoever must retain the following
39
	   acknowledgment:
40

    
41
	"This product includes software developed by the pfSense Project
42
	for use in the pfSense software distribution (http://www.pfsense.org/).
43

    
44
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
45
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
48
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
	OF THE POSSIBILITY OF SUCH DAMAGE.
56
*/
57

    
58
function activate_powerd() {
59
	global $config, $g;
60

    
61
	if (is_process_running("powerd")) {
62
		exec("/usr/bin/killall powerd");
63
	}
64
	if (isset($config['system']['powerd_enable'])) {
65
		if ($g["platform"] == "nanobsd") {
66
			exec("/sbin/kldload cpufreq");
67
		}
68

    
69
		$ac_mode = "hadp";
70
		if (!empty($config['system']['powerd_ac_mode'])) {
71
			$ac_mode = $config['system']['powerd_ac_mode'];
72
		}
73

    
74
		$battery_mode = "hadp";
75
		if (!empty($config['system']['powerd_battery_mode'])) {
76
			$battery_mode = $config['system']['powerd_battery_mode'];
77
		}
78

    
79
		$normal_mode = "hadp";
80
		if (!empty($config['system']['powerd_normal_mode'])) {
81
			$normal_mode = $config['system']['powerd_normal_mode'];
82
		}
83

    
84
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
85
	}
86
}
87

    
88
function get_default_sysctl_value($id) {
89
	global $sysctls;
90

    
91
	if (isset($sysctls[$id])) {
92
		return $sysctls[$id];
93
	}
94
}
95

    
96
function get_sysctl_descr($sysctl) {
97
	unset($output);
98
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
99

    
100
	return $output[0];
101
}
102

    
103
function system_get_sysctls() {
104
	global $config, $sysctls;
105

    
106
	$disp_sysctl = array();
107
	$disp_cache = array();
108
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
109
		foreach ($config['sysctl']['item'] as $id => $tunable) {
110
			if ($tunable['value'] == "default") {
111
				$value = get_default_sysctl_value($tunable['tunable']);
112
			} else {
113
				$value = $tunable['value'];
114
			}
115

    
116
			$disp_sysctl[$id] = $tunable;
117
			$disp_sysctl[$id]['modified'] = true;
118
			$disp_cache[$tunable['tunable']] = 'set';
119
		}
120
	}
121

    
122
	foreach ($sysctls as $sysctl => $value) {
123
		if (isset($disp_cache[$sysctl])) {
124
			continue;
125
		}
126

    
127
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
128
	}
129
	unset($disp_cache);
130
	return $disp_sysctl;
131
}
132

    
133
function activate_sysctls() {
134
	global $config, $g, $sysctls;
135

    
136
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
137
		foreach ($config['sysctl']['item'] as $tunable) {
138
			if ($tunable['value'] == "default") {
139
				$value = get_default_sysctl_value($tunable['tunable']);
140
			} else {
141
				$value = $tunable['value'];
142
			}
143

    
144
			$sysctls[$tunable['tunable']] = $value;
145
		}
146
	}
147

    
148
	set_sysctl($sysctls);
149
}
150

    
151
function system_resolvconf_generate($dynupdate = false) {
152
	global $config, $g;
153

    
154
	if (isset($config['system']['developerspew'])) {
155
		$mt = microtime();
156
		echo "system_resolvconf_generate() being called $mt\n";
157
	}
158

    
159
	$syscfg = $config['system'];
160

    
161
	if ((((isset($config['dnsmasq']['enable'])) &&
162
	      (empty($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
163
	      (empty($config['dnsmasq']['interface']) ||
164
	       in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
165
	     ((isset($config['unbound']['enable'])) &&
166
	      (empty($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
167
	      (empty($config['unbound']['active_interface']) ||
168
	       in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
169
	       in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
170
	     (!isset($config['system']['dnslocalhost']))) {
171
		$resolvconf .= "nameserver 127.0.0.1\n";
172
	}
173

    
174
	if (isset($syscfg['dnsallowoverride'])) {
175
		/* get dynamically assigned DNS servers (if any) */
176
		$ns = array_unique(get_searchdomains());
177
		foreach ($ns as $searchserver) {
178
			if ($searchserver) {
179
				$resolvconf .= "search {$searchserver}\n";
180
			}
181
		}
182
		$ns = array_unique(get_nameservers());
183
		foreach ($ns as $nameserver) {
184
			if ($nameserver) {
185
				$resolvconf .= "nameserver $nameserver\n";
186
			}
187
		}
188
	} else {
189
		$ns = array();
190
		// Do not create blank search/domain lines, it can break tools like dig.
191
		if ($syscfg['domain']) {
192
			$resolvconf .= "search {$syscfg['domain']}\n";
193
		}
194
	}
195
	if (is_array($syscfg['dnsserver'])) {
196
		foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
197
			if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
198
				$resolvconf .= "nameserver $sys_dnsserver\n";
199
			}
200
		}
201
	}
202

    
203
	// Add EDNS support
204
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
205
		$resolvconf .= "options edns0\n";
206
	}
207

    
208
	$dnslock = lock('resolvconf', LOCK_EX);
209

    
210
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
211
	if (!$fd) {
212
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
213
		unlock($dnslock);
214
		return 1;
215
	}
216

    
217
	fwrite($fd, $resolvconf);
218
	fclose($fd);
219

    
220
	// Prevent resolvconf(8) from rewriting our resolv.conf
221
	$fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
222
	if (!$fd) {
223
		printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
224
		return 1;
225
	}
226
	fwrite($fd, "resolv_conf=\"/dev/null\"\n");
227
	fclose($fd);
228

    
229
	if (!platform_booting()) {
230
		/* restart dhcpd (nameservers may have changed) */
231
		if (!$dynupdate) {
232
			services_dhcpd_configure();
233
		}
234
	}
235

    
236
	/* setup static routes for DNS servers. */
237
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
238
		/* setup static routes for dns servers */
239
		$dnsgw = "dns{$dnscounter}gw";
240
		if (isset($config['system'][$dnsgw])) {
241
			if (empty($config['system'][$dnsgw]) ||
242
			    $config['system'][$dnsgw] == "none") {
243
				continue;
244
			}
245
			$gwname = $config['system'][$dnsgw];
246
			$gatewayip = lookup_gateway_ip_by_name($gwname);
247
			$inet6 = is_ipaddrv6($gatewayip) ? '-inet6 ' : '';
248
			/* dns server array starts at 0 */
249
			$dnsserver = $syscfg['dnsserver'][$dnscounter - 1];
250

    
251
			if (is_ipaddr($gatewayip)) {
252
				$cmd = 'change';
253
			} else {
254
				/* Remove old route when disable gw */
255
				$cmd = 'delete';
256
				$gatewayip = '';
257
			}
258

    
259
			mwexec("/sbin/route {$cmd} -host {$inet6}{$dnsserver} {$gatewayip}");
260
			if (isset($config['system']['route-debug'])) {
261
				$mt = microtime();
262
				log_error("ROUTING debug: $mt - route {$cmd} -host {$inet6}{$dnsserver} {$gatewayip}");
263
			}
264
		}
265
	}
266

    
267
	unlock($dnslock);
268

    
269
	return 0;
270
}
271

    
272
function get_searchdomains() {
273
	global $config, $g;
274

    
275
	$master_list = array();
276

    
277
	// Read in dhclient nameservers
278
	$search_list = glob("/var/etc/searchdomain_*");
279
	if (is_array($search_list)) {
280
		foreach ($search_list as $fdns) {
281
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
282
			if (!is_array($contents)) {
283
				continue;
284
			}
285
			foreach ($contents as $dns) {
286
				if (is_hostname($dns)) {
287
					$master_list[] = $dns;
288
				}
289
			}
290
		}
291
	}
292

    
293
	return $master_list;
294
}
295

    
296
function get_nameservers() {
297
	global $config, $g;
298
	$master_list = array();
299

    
300
	// Read in dhclient nameservers
301
	$dns_lists = glob("/var/etc/nameserver_*");
302
	if (is_array($dns_lists)) {
303
		foreach ($dns_lists as $fdns) {
304
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
305
			if (!is_array($contents)) {
306
				continue;
307
			}
308
			foreach ($contents as $dns) {
309
				if (is_ipaddr($dns)) {
310
					$master_list[] = $dns;
311
				}
312
			}
313
		}
314
	}
315

    
316
	// Read in any extra nameservers
317
	if (file_exists("/var/etc/nameservers.conf")) {
318
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
319
		if (is_array($dns_s)) {
320
			foreach ($dns_s as $dns) {
321
				if (is_ipaddr($dns)) {
322
					$master_list[] = $dns;
323
				}
324
			}
325
		}
326
	}
327

    
328
	return $master_list;
329
}
330

    
331
function system_hosts_generate() {
332
	global $config, $g;
333
	if (isset($config['system']['developerspew'])) {
334
		$mt = microtime();
335
		echo "system_hosts_generate() being called $mt\n";
336
	}
337

    
338
	$syscfg = $config['system'];
339
	// prefer dnsmasq for hosts generation where it's enabled. It relies
340
	// on hosts for name resolution of its overrides, unbound does not.
341
	if (isset($config['dnsmasq']) && isset($config['dnsmasq']['enable'])) {
342
		$dnsmasqcfg = $config['dnsmasq'];
343
	} else {
344
		$dnsmasqcfg = $config['unbound'];
345
	}
346

    
347
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
348
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
349
	$lhosts = "";
350
	$dhosts = "";
351

    
352
	if ($config['interfaces']['lan']) {
353
		$cfgip = get_interface_ip("lan");
354
		if (is_ipaddr($cfgip)) {
355
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
356
		}
357
		$cfgipv6 = get_interface_ipv6("lan");
358
		if (is_ipaddrv6($cfgipv6)) {
359
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
360
		}
361
	} else {
362
		$sysiflist = get_configured_interface_list();
363
		$hosts_if_found = false;
364
		foreach ($sysiflist as $sysif) {
365
			if (!interface_has_gateway($sysif)) {
366
				$cfgip = get_interface_ip($sysif);
367
				if (is_ipaddr($cfgip)) {
368
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
369
					$hosts_if_found = true;
370
				}
371
				$cfgipv6 = get_interface_ipv6($sysif);
372
				if (is_ipaddrv6($cfgipv6)) {
373
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
374
					$hosts_if_found = true;
375
				}
376
				if ($hosts_if_found == true) {
377
					break;
378
				}
379
			}
380
		}
381
	}
382

    
383
	if (isset($dnsmasqcfg['enable'])) {
384
		if (!is_array($dnsmasqcfg['hosts'])) {
385
			$dnsmasqcfg['hosts'] = array();
386
		}
387

    
388
		foreach ($dnsmasqcfg['hosts'] as $host) {
389
			if ($host['host'] || $host['host'] == "0") {
390
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
391
			} else {
392
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
393
			}
394
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item'])) {
395
				continue;
396
			}
397
			foreach ($host['aliases']['item'] as $alias) {
398
				if ($alias['host'] || $alias['host'] == "0") {
399
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
400
				} else {
401
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
402
				}
403
			}
404
		}
405
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
406
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
407
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
408
					foreach ($dhcpifconf['staticmap'] as $host) {
409
						if ($host['ipaddr'] && $host['hostname'] && $host['domain']) {
410
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
411
						} else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain']) {
412
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
413
						} else if ($host['ipaddr'] && $host['hostname']) {
414
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
415
						}
416
					}
417
				}
418
			}
419
		}
420
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
421
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
422
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
423
					$isdelegated = $config['interfaces'][$dhcpif]['ipaddrv6'] == 'track6';
424
					foreach ($dhcpifconf['staticmap'] as $host) {
425
						$ipaddrv6 = $host['ipaddrv6'];
426
						if ($ipaddrv6 && $host['hostname']) {
427
							if ($isdelegated) {
428
								$trackifname = $config['interfaces'][$dhcpif]['track6-interface'];
429
								$trackcfg = $config['interfaces'][$trackifname];
430
								$pdlen = 64 - $trackcfg['dhcp6-ia-pd-len'];
431
								$ipaddrv6 = merge_ipv6_delegated_prefix(get_interface_ipv6($dhcpif), $ipaddrv6, $pdlen);
432
							}
433
							if ($host['domain']) {
434
								$dhosts .= "{$ipaddrv6}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
435
							} else if ($dhcpifconf['domain']) {
436
								$dhosts .= "{$ipaddrv6}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
437
							} else {
438
								$dhosts .= "{$ipaddrv6}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
439
							}
440
						}
441
					}
442
				}
443
			}
444
		}
445

    
446
		if (isset($dnsmasqcfg['dhcpfirst'])) {
447
			$hosts .= $dhosts . $lhosts;
448
		} else {
449
			$hosts .= $lhosts . $dhosts;
450
		}
451
	}
452

    
453
	/*
454
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be
455
	 * killed before writing to hosts files.
456
	 */
457
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
458
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
459
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
460
	}
461
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
462
	if (!$fd) {
463
		log_error(gettext("Error: cannot open hosts file in system_hosts_generate()."));
464
		return 1;
465
	}
466
	fwrite($fd, $hosts);
467
	fclose($fd);
468

    
469
	if (isset($config['unbound']['enable'])) {
470
		require_once("unbound.inc");
471
		unbound_hosts_generate();
472
	}
473

    
474
	return 0;
475
}
476

    
477
function system_dhcpleases_configure() {
478
	global $config, $g;
479

    
480
	/* Start the monitoring process for dynamic dhcpclients. */
481
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
482
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
483
		/* Make sure we do not error out */
484
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
485
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
486
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
487
		}
488

    
489
		if (isset($config['unbound']['enable'])) {
490
			$dns_pid = "unbound.pid";
491
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
492
		} else {
493
			$dns_pid = "dnsmasq.pid";
494
			$unbound_conf = "";
495
		}
496

    
497
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
498
		if (isvalidpid($pidfile)) {
499
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
500
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
501
			if (intval($retval) == 0) {
502
				sigkillbypid($pidfile, "HUP");
503
				return;
504
			} else {
505
				sigkillbypid($pidfile, "TERM");
506
			}
507
		}
508

    
509
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
510
		if (is_process_running("dhcpleases")) {
511
			sigkillbyname('dhcpleases', "TERM");
512
		}
513
		@unlink($pidfile);
514
		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");
515
	} else {
516
		sigkillbypid($pidfile, "TERM");
517
		@unlink($pidfile);
518
	}
519
}
520

    
521
function system_hostname_configure() {
522
	global $config, $g;
523
	if (isset($config['system']['developerspew'])) {
524
		$mt = microtime();
525
		echo "system_hostname_configure() being called $mt\n";
526
	}
527

    
528
	$syscfg = $config['system'];
529

    
530
	/* set hostname */
531
	$status = mwexec("/bin/hostname " .
532
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
533

    
534
	/* Setup host GUID ID.  This is used by ZFS. */
535
	mwexec("/etc/rc.d/hostid start");
536

    
537
	return $status;
538
}
539

    
540
function system_routing_configure($interface = "") {
541
	global $config, $g;
542

    
543
	if (isset($config['system']['developerspew'])) {
544
		$mt = microtime();
545
		echo "system_routing_configure() being called $mt\n";
546
	}
547

    
548
	$gatewayip = "";
549
	$interfacegw = "";
550
	$gatewayipv6 = "";
551
	$interfacegwv6 = "";
552
	$foundgw = false;
553
	$foundgwv6 = false;
554
	/* tack on all the hard defined gateways as well */
555
	if (is_array($config['gateways']['gateway_item'])) {
556
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
557
		foreach	($config['gateways']['gateway_item'] as $gateway) {
558
			if (isset($gateway['defaultgw'])) {
559
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
560
					if (strpos($gateway['gateway'], ":")) {
561
						continue;
562
					}
563
					if ($gateway['gateway'] == "dynamic") {
564
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
565
					}
566
					$gatewayip = $gateway['gateway'];
567
					$interfacegw = $gateway['interface'];
568
					if (!empty($gateway['interface'])) {
569
						$defaultif = get_real_interface($gateway['interface']);
570
						if ($defaultif) {
571
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
572
						}
573
					}
574
					$foundgw = true;
575
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
576
					if ($gateway['gateway'] == "dynamic") {
577
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
578
					}
579
					$gatewayipv6 = $gateway['gateway'];
580
					$interfacegwv6 = $gateway['interface'];
581
					if (!empty($gateway['interface'])) {
582
						$defaultifv6 = get_real_interface($gateway['interface']);
583
						if ($defaultifv6) {
584
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
585
						}
586
					}
587
					$foundgwv6 = true;
588
				}
589
			}
590
			if ($foundgw === true && $foundgwv6 === true) {
591
				break;
592
			}
593
		}
594
	}
595
	if ($foundgw == false) {
596
		$defaultif = get_real_interface("wan");
597
		$interfacegw = "wan";
598
		$gatewayip = get_interface_gateway("wan");
599
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
600
	}
601
	if ($foundgwv6 == false) {
602
		$defaultifv6 = get_real_interface("wan");
603
		$interfacegwv6 = "wan";
604
		$gatewayipv6 = get_interface_gateway_v6("wan");
605
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
606
	}
607
	$dont_add_route = false;
608
	/* if OLSRD is enabled, allow WAN to house DHCP. */
609
	if (is_array($config['installedpackages']['olsrd'])) {
610
		foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
611
			if (($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
612
				$dont_add_route = true;
613
				log_error(gettext("Not adding default route because OLSR dynamic gateway is enabled."));
614
				break;
615
			}
616
		}
617
	}
618

    
619
	$gateways_arr = return_gateways_array(false, true);
620
	foreach ($gateways_arr as $gateway) {
621
		// setup static interface routes for nonlocal gateways
622
		if (isset($gateway["nonlocalgateway"])) {
623
			$srgatewayip = $gateway['gateway'];
624
			$srinterfacegw = $gateway['interface'];
625
			if (is_ipaddr($srgatewayip) && !empty($srinterfacegw)) {
626
				$inet = (!is_ipaddrv4($srgatewayip) ? "-inet6" : "-inet");
627
				$cmd = "/sbin/route change {$inet} " . escapeshellarg($srgatewayip) . " ";
628
				mwexec($cmd . "-iface " . escapeshellarg($srinterfacegw));
629
				if (isset($config['system']['route-debug'])) {
630
					$mt = microtime();
631
					log_error("ROUTING debug: $mt - $cmd -iface $srinterfacegw ");
632
				}
633
			}
634
		}
635
	}
636

    
637
	if ($dont_add_route == false) {
638
		if (!empty($interface) && $interface != $interfacegw) {
639
			;
640
		} else if (is_ipaddrv4($gatewayip)) {
641
			log_error(sprintf(gettext("ROUTING: setting default route to %s"), $gatewayip));
642
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
643
		}
644

    
645
		if (!empty($interface) && $interface != $interfacegwv6) {
646
			;
647
		} else if (is_ipaddrv6($gatewayipv6)) {
648
			$ifscope = "";
649
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
650
				$ifscope = "%{$defaultifv6}";
651
			}
652
			log_error(sprintf(gettext("ROUTING: setting IPv6 default route to %s"), $gatewayipv6 . $ifscope));
653
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
654
		}
655
	}
656

    
657
	system_staticroutes_configure($interface, false);
658

    
659
	return 0;
660
}
661

    
662
function system_staticroutes_configure($interface = "", $update_dns = false) {
663
	global $config, $g, $aliastable;
664

    
665
	$filterdns_list = array();
666

    
667
	$static_routes = get_staticroutes(false, true);
668
	if (count($static_routes)) {
669
		$gateways_arr = return_gateways_array(false, true);
670

    
671
		foreach ($static_routes as $rtent) {
672
			if (empty($gateways_arr[$rtent['gateway']])) {
673
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
674
				continue;
675
			}
676
			$gateway = $gateways_arr[$rtent['gateway']];
677
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
678
				continue;
679
			}
680

    
681
			$gatewayip = $gateway['gateway'];
682
			$interfacegw = $gateway['interface'];
683

    
684
			$blackhole = "";
685
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
686
				$blackhole = "-blackhole";
687
			}
688

    
689
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
690
				continue;
691
			}
692

    
693
			$dnscache = array();
694
			if ($update_dns === true) {
695
				if (is_subnet($rtent['network'])) {
696
					continue;
697
				}
698
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
699
				if (empty($dnscache)) {
700
					continue;
701
				}
702
			}
703

    
704
			if (is_subnet($rtent['network'])) {
705
				$ips = array($rtent['network']);
706
			} else {
707
				if (!isset($rtent['disabled'])) {
708
					$filterdns_list[] = $rtent['network'];
709
				}
710
				$ips = add_hostname_to_watch($rtent['network']);
711
			}
712

    
713
			foreach ($dnscache as $ip) {
714
				if (in_array($ip, $ips)) {
715
					continue;
716
				}
717
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
718
				if (isset($config['system']['route-debug'])) {
719
					$mt = microtime();
720
					log_error("ROUTING debug: $mt - route delete $ip ");
721
				}
722
			}
723

    
724
			if (isset($rtent['disabled'])) {
725
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
726
				foreach ($ips as $ip) {
727
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
728
					if (isset($config['system']['route-debug'])) {
729
						$mt = microtime();
730
						log_error("ROUTING debug: $mt - route delete $ip ");
731
					}
732
				}
733
				continue;
734
			}
735

    
736
			foreach ($ips as $ip) {
737
				if (is_ipaddrv4($ip)) {
738
					$ip .= "/32";
739
				}
740
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
741

    
742
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
743

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

    
746
				if (is_subnet($ip)) {
747
					if (is_ipaddr($gatewayip)) {
748
						mwexec($cmd . escapeshellarg($gatewayip));
749
						if (isset($config['system']['route-debug'])) {
750
							$mt = microtime();
751
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
752
						}
753
					} else if (!empty($interfacegw)) {
754
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
755
						if (isset($config['system']['route-debug'])) {
756
							$mt = microtime();
757
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
758
						}
759
					}
760
				}
761
			}
762
		}
763
		unset($gateways_arr);
764
	}
765
	unset($static_routes);
766

    
767
	if ($update_dns === false) {
768
		if (count($filterdns_list)) {
769
			$interval = 60;
770
			$hostnames = "";
771
			array_unique($filterdns_list);
772
			foreach ($filterdns_list as $hostname) {
773
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
774
			}
775
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
776
			unset($hostnames);
777

    
778
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
779
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
780
			} else {
781
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
782
			}
783
		} else {
784
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
785
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
786
		}
787
	}
788
	unset($filterdns_list);
789

    
790
	return 0;
791
}
792

    
793
function system_routing_enable() {
794
	global $config, $g;
795
	if (isset($config['system']['developerspew'])) {
796
		$mt = microtime();
797
		echo "system_routing_enable() being called $mt\n";
798
	}
799

    
800
	set_sysctl(array(
801
		"net.inet.ip.forwarding" => "1",
802
		"net.inet6.ip6.forwarding" => "1"
803
	));
804

    
805
	return;
806
}
807

    
808
function system_syslogd_fixup_server($server) {
809
	/* If it's an IPv6 IP alone, encase it in brackets */
810
	if (is_ipaddrv6($server)) {
811
		return "[$server]";
812
	} else {
813
		return $server;
814
	}
815
}
816

    
817
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
818
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
819
	$facility .= " ".
820
	$remote_servers = "";
821
	$pad_to  = max(strlen($facility), 56);
822
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
823
	if (isset($syslogcfg['enable'])) {
824
		if ($syslogcfg['remoteserver']) {
825
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
826
		}
827
		if ($syslogcfg['remoteserver2']) {
828
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
829
		}
830
		if ($syslogcfg['remoteserver3']) {
831
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
832
		}
833
	}
834
	return $remote_servers;
835
}
836

    
837
function clear_log_file($logfile = "/var/log/system.log", $restart_syslogd = true) {
838
	global $config, $g;
839
	if ($restart_syslogd) {
840
		exec("/usr/bin/killall syslogd");
841
	}
842
	if (isset($config['system']['disablesyslogclog'])) {
843
		unlink($logfile);
844
		touch($logfile);
845
	} else {
846
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "511488";
847
		$log_size = isset($config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize']) ? $config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize'] : $log_size;
848
		exec("/usr/local/sbin/clog -i -s {$log_size} " . escapeshellarg($logfile));
849
	}
850
	if ($restart_syslogd) {
851
		system_syslogd_start();
852
	}
853
}
854

    
855
function clear_all_log_files($restart = false) {
856
	global $g;
857
	exec("/usr/bin/killall syslogd");
858

    
859
	$log_files = array("system", "filter", "dhcpd", "vpn", "pptps", "poes", "l2tps", "openvpn", "portalauth", "ipsec", "ppp", "relayd", "wireless", "nginx", "ntpd", "gateways", "resolver", "routing");
860
	foreach ($log_files as $lfile) {
861
		clear_log_file("{$g['varlog_path']}/{$lfile}.log", false);
862
	}
863

    
864
	if ($restart) {
865
		system_syslogd_start();
866
		killbyname("dhcpd");
867
		services_dhcpd_configure();
868
	}
869
	return;
870
}
871

    
872
function system_syslogd_start() {
873
	global $config, $g;
874
	if (isset($config['system']['developerspew'])) {
875
		$mt = microtime();
876
		echo "system_syslogd_start() being called $mt\n";
877
	}
878

    
879
	mwexec("/etc/rc.d/hostid start");
880

    
881
	$syslogcfg = $config['syslog'];
882

    
883
	if (platform_booting()) {
884
		echo gettext("Starting syslog...");
885
	}
886

    
887
	// Which logging type are we using this week??
888
	if (isset($config['system']['disablesyslogclog'])) {
889
		$log_directive = "";
890
		$log_create_directive = "/usr/bin/touch ";
891
		$log_size = "";
892
	} else { // Defaults to CLOG
893
		$log_directive = "%";
894
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
895
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
896
	}
897

    
898
	$syslogd_extra = "";
899
	if (isset($syslogcfg)) {
900
		$separatelogfacilities = array('ntp', 'ntpd', 'ntpdate', 'charon', 'ipsec_starter', 'openvpn', 'pptps', 'poes', 'l2tps', 'relayd', 'hostapd', 'dnsmasq', 'filterdns', 'unbound', 'dhcpd', 'dhcrelay', 'dhclient', 'dhcp6c', 'dpinger', 'radvd', 'routed', 'olsrd', 'zebra', 'ospfd', 'bgpd', 'miniupnpd', 'filterlog');
901
		$syslogconf = "";
902
		if ($config['installedpackages']['package']) {
903
			foreach ($config['installedpackages']['package'] as $package) {
904
				if ($package['logging']) {
905
					array_push($separatelogfacilities, $package['logging']['facilityname']);
906
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
907
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
908
					}
909
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
910
				}
911
			}
912
		}
913
		$facilitylist = implode(',', array_unique($separatelogfacilities));
914
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
915
		if (!isset($syslogcfg['disablelocallogging'])) {
916
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
917
		}
918

    
919
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
920
		if (!isset($syslogcfg['disablelocallogging'])) {
921
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
922
		}
923

    
924
		$syslogconf .= "!ppp\n";
925
		if (!isset($syslogcfg['disablelocallogging'])) {
926
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
927
		}
928

    
929
		$syslogconf .= "!pptps\n";
930
		if (!isset($syslogcfg['disablelocallogging'])) {
931
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
932
		}
933

    
934
		$syslogconf .= "!poes\n";
935
		if (!isset($syslogcfg['disablelocallogging'])) {
936
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
937
		}
938

    
939
		$syslogconf .= "!l2tps\n";
940
		if (!isset($syslogcfg['disablelocallogging'])) {
941
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
942
		}
943

    
944
		$syslogconf .= "!charon,ipsec_starter\n";
945
		if (!isset($syslogcfg['disablelocallogging'])) {
946
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
947
		}
948
		if (isset($syslogcfg['vpn'])) {
949
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
950
		}
951

    
952
		$syslogconf .= "!openvpn\n";
953
		if (!isset($syslogcfg['disablelocallogging'])) {
954
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
955
		}
956
		if (isset($syslogcfg['vpn'])) {
957
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
958
		}
959

    
960
		$syslogconf .= "!dpinger\n";
961
		if (!isset($syslogcfg['disablelocallogging'])) {
962
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
963
		}
964
		if (isset($syslogcfg['dpinger'])) {
965
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
966
		}
967

    
968
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
969
		if (!isset($syslogcfg['disablelocallogging'])) {
970
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
971
		}
972

    
973
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c,dhcpleases,dhcpleases6\n";
974
		if (!isset($syslogcfg['disablelocallogging'])) {
975
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
976
		}
977
		if (isset($syslogcfg['dhcp'])) {
978
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
979
		}
980

    
981
		$syslogconf .= "!relayd\n";
982
		if (!isset($syslogcfg['disablelocallogging'])) {
983
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
984
		}
985
		if (isset($syslogcfg['relayd'])) {
986
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
987
		}
988

    
989
		$syslogconf .= "!hostapd\n";
990
		if (!isset($syslogcfg['disablelocallogging'])) {
991
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
992
		}
993
		if (isset($syslogcfg['hostapd'])) {
994
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
995
		}
996

    
997
		$syslogconf .= "!filterlog\n";
998
		if (!isset($syslogcfg['disablelocallogging'])) {
999
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
1000
		}
1001

    
1002
		if (isset($syslogcfg['filter'])) {
1003
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1004
		}
1005

    
1006
		$syslogconf .= "!-{$facilitylist}\n";
1007
		if (!isset($syslogcfg['disablelocallogging'])) {
1008
			$syslogconf .= <<<EOD
1009
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
1010
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
1011
local5.*							{$log_directive}{$g['varlog_path']}/nginx.log
1012
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
1013
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;news.err;local0.none;local3.none;local4.none;local7.none;security.*;auth.info;authpriv.info;daemon.info	{$log_directive}{$g['varlog_path']}/system.log
1014
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
1015
*.emerg								*
1016

    
1017
EOD;
1018
		}
1019
		if (isset($syslogcfg['vpn'])) {
1020
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
1021
		}
1022
		if (isset($syslogcfg['portalauth'])) {
1023
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
1024
		}
1025
		if (isset($syslogcfg['dhcp'])) {
1026
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
1027
		}
1028
		if (isset($syslogcfg['system'])) {
1029
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg;*.notice;kern.debug;lpr.info;mail.crit;news.err;local0.none;local3.none;local7.none;security.*;auth.info;authpriv.info;daemon.info");
1030
		}
1031
		if (isset($syslogcfg['logall'])) {
1032
			// Make everything mean everything, including facilities excluded above.
1033
			$syslogconf .= "!*\n";
1034
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1035
		}
1036

    
1037
		if (isset($syslogcfg['zmqserver'])) {
1038
				$syslogconf .= <<<EOD
1039
*.*								^{$syslogcfg['zmqserver']}
1040

    
1041
EOD;
1042
		}
1043
		/* write syslog.conf */
1044
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
1045
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
1046
			unset($syslogconf);
1047
			return 1;
1048
		}
1049
		unset($syslogconf);
1050

    
1051
		// Ensure that the log directory exists
1052
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
1053
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
1054
		}
1055

    
1056
		$sourceip = "";
1057
		if (!empty($syslogcfg['sourceip'])) {
1058
			if ($syslogcfg['ipproto'] == "ipv6") {
1059
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
1060
				if (!is_ipaddr($ifaddr)) {
1061
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
1062
				}
1063
			} else {
1064
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1065
				if (!is_ipaddr($ifaddr)) {
1066
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1067
				}
1068
			}
1069
			if (is_ipaddr($ifaddr)) {
1070
				$sourceip = "-b {$ifaddr}";
1071
			}
1072
		}
1073

    
1074
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1075
	}
1076

    
1077
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1078
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1079
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1080
	}
1081

    
1082
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1083
		// if it still hasn't responded to the TERM, KILL it.
1084
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1085
		usleep(100000);
1086
	}
1087

    
1088

    
1089
	$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}");
1090

    
1091
	if (platform_booting()) {
1092
		echo gettext("done.") . "\n";
1093
	}
1094

    
1095
	return $retval;
1096
}
1097

    
1098
function system_webgui_create_certificate() {
1099
	global $config, $g;
1100

    
1101
	if (!is_array($config['ca'])) {
1102
		$config['ca'] = array();
1103
	}
1104
	$a_ca =& $config['ca'];
1105
	if (!is_array($config['cert'])) {
1106
		$config['cert'] = array();
1107
	}
1108
	$a_cert =& $config['cert'];
1109
	log_error(gettext("Creating SSL Certificate for this host"));
1110

    
1111
	$cert = array();
1112
	$cert['refid'] = uniqid();
1113
	$cert['descr'] = sprintf(gettext("webConfigurator default (%s)"), $cert['refid']);
1114

    
1115
	$dn = array(
1116
		'countryName' => "US",
1117
		'stateOrProvinceName' => "State",
1118
		'localityName' => "Locality",
1119
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
1120
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
1121
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
1122
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
1123
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
1124
		while ($ssl_err = openssl_error_string()) {
1125
			log_error(sprintf(gettext("Error creating WebGUI Certificate: openssl library returns: %s"), $ssl_err));
1126
		}
1127
		error_reporting($old_err_level);
1128
		return null;
1129
	}
1130
	error_reporting($old_err_level);
1131

    
1132
	$a_cert[] = $cert;
1133
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1134
	write_config(sprintf(gettext("Generated new self-signed HTTPS certificate (%s)"), $cert['refid']));
1135
	return $cert;
1136
}
1137

    
1138
function system_webgui_start() {
1139
	global $config, $g;
1140

    
1141
	if (platform_booting()) {
1142
		echo gettext("Starting webConfigurator...");
1143
	}
1144

    
1145
	chdir($g['www_path']);
1146

    
1147
	/* defaults */
1148
	$portarg = "80";
1149
	$crt = "";
1150
	$key = "";
1151
	$ca = "";
1152

    
1153
	/* non-standard port? */
1154
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1155
		$portarg = "{$config['system']['webgui']['port']}";
1156
	}
1157

    
1158
	if ($config['system']['webgui']['protocol'] == "https") {
1159
		// Ensure that we have a webConfigurator CERT
1160
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1161
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1162
			$cert = system_webgui_create_certificate();
1163
		}
1164
		$crt = base64_decode($cert['crt']);
1165
		$key = base64_decode($cert['prv']);
1166

    
1167
		if (!$config['system']['webgui']['port']) {
1168
			$portarg = "443";
1169
		}
1170
		$ca = ca_chain($cert);
1171
	}
1172

    
1173
	/* generate nginx configuration */
1174
	system_generate_nginx_config("{$g['varetc_path']}/nginx-webConfigurator.conf",
1175
		$crt, $key, $ca, "nginx-webConfigurator.pid", $portarg, "/usr/local/www/",
1176
		"cert.crt", "cert.key");
1177

    
1178
	/* kill any running nginx */
1179
	killbypid("{$g['varrun_path']}/nginx-webConfigurator.pid");
1180

    
1181
	sleep(1);
1182

    
1183
	@unlink("{$g['varrun_path']}/nginx-webConfigurator.pid");
1184

    
1185
	/* start nginx */
1186
	$res = mwexec("/usr/local/sbin/nginx -c {$g['varetc_path']}/nginx-webConfigurator.conf");
1187

    
1188
	if (platform_booting()) {
1189
		if ($res == 0) {
1190
			echo gettext("done.") . "\n";
1191
		} else {
1192
			echo gettext("failed!") . "\n";
1193
		}
1194
	}
1195

    
1196
	return $res;
1197
}
1198

    
1199
function system_generate_nginx_config($filename,
1200
	$cert,
1201
	$key,
1202
	$ca,
1203
	$pid_file,
1204
	$port = 80,
1205
	$document_root = "/usr/local/www/",
1206
	$cert_location = "cert.crt",
1207
	$key_location = "cert.key",
1208
	$captive_portal = false) {
1209

    
1210
	global $config, $g;
1211

    
1212
	if (isset($config['system']['developerspew'])) {
1213
		$mt = microtime();
1214
		echo "system_generate_nginx_config() being called $mt\n";
1215
	}
1216

    
1217
	if ($captive_portal !== false) {
1218
		$cp_interfaces = explode(",", $config['captiveportal'][$captive_portal]['interface']);
1219
		$cp_hostcheck = "";
1220
		foreach ($cp_interfaces as $cpint) {
1221
			$cpint_ip = get_interface_ip($cpint);
1222
			if (is_ipaddr($cpint_ip)) {
1223
				$cp_hostcheck .= "\t\tif (\$http_host ~* $cpint_ip) {\n";
1224
				$cp_hostcheck .= "\t\t\tset \$cp_redirect no;\n";
1225
				$cp_hostcheck .= "\t\t}\n";
1226
			}
1227
		}
1228
		if (isset($config['captiveportal'][$captive_portal]['httpsname']) &&
1229
		    is_domain($config['captiveportal'][$captive_portal]['httpsname'])) {
1230
			$cp_hostcheck .= "\t\tif (\$http_host ~* {$config['captiveportal'][$captive_portal]['httpsname']}) {\n";
1231
			$cp_hostcheck .= "\t\t\tset \$cp_redirect no;\n";
1232
			$cp_hostcheck .= "\t\t}\n";
1233
		}
1234
		$cp_rewrite = "\t\tif (\$cp_redirect = '') {\n";
1235
		$cp_rewrite .= "\t\t\trewrite	^ /index.php?zone=$captive_portal&redirurl=\$request_uri break;\n";
1236
		$cp_rewrite .= "\t\t}\n";
1237

    
1238
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1239
		if (empty($maxprocperip)) {
1240
			$maxprocperip = 10;
1241
		}
1242
		$captive_portal_maxprocperip = "\t\tlimit_conn addr $maxprocperip;\n";
1243
	}
1244

    
1245
	if (empty($port)) {
1246
		$nginx_port = "80";
1247
	} else {
1248
		$nginx_port = $port;
1249
	}
1250

    
1251
	$memory = get_memory();
1252
	$realmem = $memory[1];
1253

    
1254
	// Determine web GUI process settings and take into account low memory systems
1255
	if ($realmem < 255) {
1256
		$max_procs = 1;
1257
	} else {
1258
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1259
	}
1260

    
1261
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
1262
	if ($captive_portal !== false) {
1263
		if ($realmem > 135 and $realmem < 256) {
1264
			$max_procs += 1; // 2 worker processes
1265
		} else if ($realmem > 255 and $realmem < 513) {
1266
			$max_procs += 2; // 3 worker processes
1267
		} else if ($realmem > 512) {
1268
			$max_procs += 4; // 6 worker processes
1269
		}
1270
	}
1271

    
1272
	$nginx_config = <<<EOD
1273
#
1274
# nginx configuration file
1275

    
1276
pid {$g['varrun_path']}/{$pid_file};
1277

    
1278
user  root wheel;
1279
worker_processes  {$max_procs};
1280

    
1281
EOD;
1282

    
1283
	if (!isset($config['syslog']['nolognginx'])) {
1284
		$nginx_config .= "error_log  syslog:server=unix:/var/run/log,facility=local5;\n";
1285
	}
1286

    
1287
	$nginx_config .= <<<EOD
1288

    
1289
events {
1290
    worker_connections  1024;
1291
}
1292

    
1293
http {
1294
	include       /usr/local/etc/nginx/mime.types;
1295
	default_type  application/octet-stream;
1296
	add_header X-Frame-Options SAMEORIGIN;
1297
	server_tokens off;
1298

    
1299
	sendfile        on;
1300
	keepalive_timeout  65;
1301

    
1302
	access_log      syslog:server=unix:/var/run/log,facility=local5 combined;
1303

    
1304
EOD;
1305

    
1306
	if ($captive_portal !== false) {
1307
		$nginx_config .= "\tlimit_conn_zone \$binary_remote_addr zone=addr:10m;\n";
1308
	}
1309

    
1310
	if ($cert <> "" and $key <> "") {
1311
		$nginx_config .= "\n";
1312
		$nginx_config .= "\tserver {\n";
1313
		$nginx_config .= "\t\tlisten {$nginx_port} ssl;\n";
1314
		$nginx_config .= "\t\tlisten [::]:{$nginx_port} ssl;\n";
1315
		$nginx_config .= "\n";
1316
		$nginx_config .= "\t\tssl_certificate         {$g['varetc_path']}/{$cert_location};\n";
1317
		$nginx_config .= "\t\tssl_certificate_key     {$g['varetc_path']}/{$key_location};\n";
1318
		$nginx_config .= "\t\tssl_session_timeout     10m;\n";
1319
		$nginx_config .= "\t\tkeepalive_timeout       70;\n";
1320
		$nginx_config .= "\t\tssl_session_cache       shared:SSL:10m;\n";
1321
		if ($captive_portal !== false) {
1322
			// leave TLSv1.0 for CP for now for compatibility
1323
			$nginx_config .= "\t\tssl_protocols   TLSv1 TLSv1.1 TLSv1.2;\n";
1324
		} else {
1325
			$nginx_config .= "\t\tssl_protocols   TLSv1.1 TLSv1.2;\n";
1326
		}
1327
		$nginx_config .= "\t\tssl_ciphers \"EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\";\n";
1328
		$nginx_config .= "\t\tssl_prefer_server_ciphers       on;\n";
1329
		$nginx_config .= "\t\tadd_header Strict-Transport-Security \"max-age=31536000\";\n";
1330
		$nginx_config .= "\t\tadd_header X-Content-Type-Options nosniff;\n";
1331
		$nginx_config .= "\t\tssl_session_tickets off;\n";
1332
		$nginx_config .= "\t\tssl_dhparam /etc/dh-parameters.4096;\n";
1333
	} else {
1334
		$nginx_config .= "\n";
1335
		$nginx_config .= "\tserver {\n";
1336
		$nginx_config .= "\t\tlisten {$nginx_port};\n";
1337
		$nginx_config .= "\t\tlisten [::]:{$nginx_port};\n";
1338
	}
1339

    
1340
	$nginx_config .= <<<EOD
1341

    
1342
		client_max_body_size 200m;
1343

    
1344
		gzip on;
1345
		gzip_types text/plain text/css text/javascript application/x-javascript text/xml application/xml application/xml+rss application/json;
1346

    
1347

    
1348
EOD;
1349

    
1350
	if ($captive_portal !== false) {
1351
		$nginx_config .= <<<EOD
1352
$captive_portal_maxprocperip
1353
$cp_hostcheck
1354
$cp_rewrite
1355
		log_not_found off;
1356

    
1357
EOD;
1358

    
1359
	}
1360

    
1361
	$nginx_config .= <<<EOD
1362
		root "{$document_root}";
1363
		location / {
1364
			index  index.html index.htm index.php;
1365
		}
1366

    
1367
		location ~ \.php$ {
1368
			try_files \$uri =404; #  This line closes a potential security hole
1369
			# ensuring users can't execute uploaded files
1370
			# see: http://forum.nginx.org/read.php?2,88845,page=3
1371
			fastcgi_pass   unix:{$g['varrun_path']}/php-fpm.socket;
1372
			fastcgi_index  index.php;
1373
			fastcgi_param  SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
1374
			fastcgi_read_timeout 180;
1375
			include        /usr/local/etc/nginx/fastcgi_params;
1376
		}
1377
	}
1378

    
1379
EOD;
1380

    
1381
	$cert = str_replace("\r", "", $cert);
1382
	$key = str_replace("\r", "", $key);
1383

    
1384
	$cert = str_replace("\n\n", "\n", $cert);
1385
	$key = str_replace("\n\n", "\n", $key);
1386

    
1387
	if ($cert <> "" and $key <> "") {
1388
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1389
		if (!$fd) {
1390
			printf(gettext("Error: cannot open certificate file in system_webgui_start().%s"), "\n");
1391
			return 1;
1392
		}
1393
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1394
		if ($ca <> "") {
1395
			$cert_chain = $cert . "\n" . $ca;
1396
		} else {
1397
			$cert_chain = $cert;
1398
		}
1399
		fwrite($fd, $cert_chain);
1400
		fclose($fd);
1401
		$fd = fopen("{$g['varetc_path']}/{$key_location}", "w");
1402
		if (!$fd) {
1403
			printf(gettext("Error: cannot open certificate key file in system_webgui_start().%s"), "\n");
1404
			return 1;
1405
		}
1406
		chmod("{$g['varetc_path']}/{$key_location}", 0600);
1407
		fwrite($fd, $key);
1408
		fclose($fd);
1409
	}
1410

    
1411
	// Add HTTP to HTTPS redirect
1412
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1413
		if ($nginx_port != "443") {
1414
			$redirectport = ":{$nginx_port}";
1415
		}
1416
		$nginx_config .= <<<EOD
1417
	server {
1418
		listen 80;
1419
		listen [::]:80;
1420
		return 301 https://\$http_host$redirectport\$request_uri;
1421
	}
1422

    
1423
EOD;
1424
	}
1425

    
1426
	$nginx_config .= "}\n";
1427

    
1428
	$fd = fopen("{$filename}", "w");
1429
	if (!$fd) {
1430
		printf(gettext("Error: cannot open %s in system_generate_nginx_config().%s"), $filename, "\n");
1431
		return 1;
1432
	}
1433
	fwrite($fd, $nginx_config);
1434
	fclose($fd);
1435

    
1436
	/* nginx will fail to start if this directory does not exist. */
1437
	safe_mkdir("/var/tmp/nginx/");
1438

    
1439
	return 0;
1440

    
1441
}
1442

    
1443
function system_get_timezone_list() {
1444
	global $g;
1445

    
1446
	$file_list = array_merge(
1447
		glob("/usr/share/zoneinfo/[A-Z]*"),
1448
		glob("/usr/share/zoneinfo/*/*"),
1449
		glob("/usr/share/zoneinfo/*/*/*")
1450
	);
1451

    
1452
	if (empty($file_list)) {
1453
		$file_list[] = $g['default_timezone'];
1454
	} else {
1455
		/* Remove directories from list */
1456
		$file_list = array_filter($file_list, function($v) {
1457
			return !is_dir($v);
1458
		});
1459
	}
1460

    
1461
	/* Remove directory prefix */
1462
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1463

    
1464
	sort($file_list);
1465

    
1466
	return $file_list;
1467
}
1468

    
1469
function system_timezone_configure() {
1470
	global $config, $g;
1471
	if (isset($config['system']['developerspew'])) {
1472
		$mt = microtime();
1473
		echo "system_timezone_configure() being called $mt\n";
1474
	}
1475

    
1476
	$syscfg = $config['system'];
1477

    
1478
	if (platform_booting()) {
1479
		echo gettext("Setting timezone...");
1480
	}
1481

    
1482
	/* extract appropriate timezone file */
1483
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1484
	conf_mount_rw();
1485
	/* DO NOT remove \n otherwise tzsetup will fail */
1486
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1487
	mwexec("/usr/sbin/tzsetup -r");
1488
	conf_mount_ro();
1489

    
1490
	if (platform_booting()) {
1491
		echo gettext("done.") . "\n";
1492
	}
1493
}
1494

    
1495
function system_ntp_setup_gps($serialport) {
1496
	global $config, $g;
1497
	$gps_device = '/dev/gps0';
1498
	$serialport = '/dev/'.$serialport;
1499

    
1500
	if (!file_exists($serialport)) {
1501
		return false;
1502
	}
1503

    
1504
	conf_mount_rw();
1505
	// Create symlink that ntpd requires
1506
	unlink_if_exists($gps_device);
1507
	@symlink($serialport, $gps_device);
1508

    
1509
	$gpsbaud = '4800';
1510
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1511
		switch ($config['ntpd']['gps']['speed']) {
1512
			case '16':
1513
				$gpsbaud = '9600';
1514
				break;
1515
			case '32':
1516
				$gpsbaud = '19200';
1517
				break;
1518
			case '48':
1519
				$gpsbaud = '38400';
1520
				break;
1521
			case '64':
1522
				$gpsbaud = '57600';
1523
				break;
1524
			case '80':
1525
				$gpsbaud = '115200';
1526
				break;
1527
		}
1528
	}
1529

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

    
1533
	/* Send the following to the GPS port to initialize the GPS */
1534
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1535
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1536
	} else {
1537
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1538
	}
1539

    
1540
	/* XXX: Why not file_put_contents to the device */
1541
	@file_put_contents('/tmp/gps.init', $gps_init);
1542
	mwexec("cat /tmp/gps.init > {$serialport}");
1543

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

    
1549
	conf_mount_ro();
1550

    
1551
	return true;
1552
}
1553

    
1554
function system_ntp_setup_pps($serialport) {
1555
	global $config, $g;
1556

    
1557
	$pps_device = '/dev/pps0';
1558
	$serialport = '/dev/'.$serialport;
1559

    
1560
	if (!file_exists($serialport)) {
1561
		return false;
1562
	}
1563

    
1564
	conf_mount_rw();
1565
	// Create symlink that ntpd requires
1566
	unlink_if_exists($pps_device);
1567
	@symlink($serialport, $pps_device);
1568

    
1569
	conf_mount_ro();
1570

    
1571
	return true;
1572
}
1573

    
1574

    
1575
function system_ntp_configure($start_ntpd=true) {
1576
	global $config, $g;
1577

    
1578
	$driftfile = "/var/db/ntpd.drift";
1579
	$statsdir = "/var/log/ntp";
1580
	$gps_device = '/dev/gps0';
1581

    
1582
	safe_mkdir($statsdir);
1583

    
1584
	if (!is_array($config['ntpd'])) {
1585
		$config['ntpd'] = array();
1586
	}
1587

    
1588
	$ntpcfg = "# \n";
1589
	$ntpcfg .= "# pfSense ntp configuration file \n";
1590
	$ntpcfg .= "# \n\n";
1591
	$ntpcfg .= "tinker panic 0 \n";
1592

    
1593
	/* Add Orphan mode */
1594
	$ntpcfg .= "# Orphan mode stratum\n";
1595
	$ntpcfg .= 'tos orphan ';
1596
	if (!empty($config['ntpd']['orphan'])) {
1597
		$ntpcfg .= $config['ntpd']['orphan'];
1598
	} else {
1599
		$ntpcfg .= '12';
1600
	}
1601
	$ntpcfg .= "\n";
1602

    
1603
	/* Add PPS configuration */
1604
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
1605
	    file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
1606
	    system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1607
		$ntpcfg .= "\n";
1608
		$ntpcfg .= "# PPS Setup\n";
1609
		$ntpcfg .= 'server 127.127.22.0';
1610
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1611
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1612
			$ntpcfg .= ' prefer';
1613
		}
1614
		if (!empty($config['ntpd']['pps']['noselect'])) {
1615
			$ntpcfg .= ' noselect ';
1616
		}
1617
		$ntpcfg .= "\n";
1618
		$ntpcfg .= 'fudge 127.127.22.0';
1619
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1620
			$ntpcfg .= ' time1 ';
1621
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1622
		}
1623
		if (!empty($config['ntpd']['pps']['flag2'])) {
1624
			$ntpcfg .= ' flag2 1';
1625
		}
1626
		if (!empty($config['ntpd']['pps']['flag3'])) {
1627
			$ntpcfg .= ' flag3 1';
1628
		} else {
1629
			$ntpcfg .= ' flag3 0';
1630
		}
1631
		if (!empty($config['ntpd']['pps']['flag4'])) {
1632
			$ntpcfg .= ' flag4 1';
1633
		}
1634
		if (!empty($config['ntpd']['pps']['refid'])) {
1635
			$ntpcfg .= ' refid ';
1636
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1637
		}
1638
		$ntpcfg .= "\n";
1639
	}
1640
	/* End PPS configuration */
1641

    
1642
	/* Add GPS configuration */
1643
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
1644
	    file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
1645
	    system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1646
		$ntpcfg .= "\n";
1647
		$ntpcfg .= "# GPS Setup\n";
1648
		$ntpcfg .= 'server 127.127.20.0 mode ';
1649
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1650
			if (!empty($config['ntpd']['gps']['nmea'])) {
1651
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1652
			}
1653
			if (!empty($config['ntpd']['gps']['speed'])) {
1654
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1655
			}
1656
			if (!empty($config['ntpd']['gps']['subsec'])) {
1657
				$ntpmode += 128;
1658
			}
1659
			$ntpcfg .= (string) $ntpmode;
1660
		} else {
1661
			$ntpcfg .= '0';
1662
		}
1663
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1664
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1665
			$ntpcfg .= ' prefer';
1666
		}
1667
		if (!empty($config['ntpd']['gps']['noselect'])) {
1668
			$ntpcfg .= ' noselect ';
1669
		}
1670
		$ntpcfg .= "\n";
1671
		$ntpcfg .= 'fudge 127.127.20.0';
1672
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1673
			$ntpcfg .= ' time1 ';
1674
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1675
		}
1676
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1677
			$ntpcfg .= ' time2 ';
1678
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1679
		}
1680
		if (!empty($config['ntpd']['gps']['flag1'])) {
1681
			$ntpcfg .= ' flag1 1';
1682
		} else {
1683
			$ntpcfg .= ' flag1 0';
1684
		}
1685
		if (!empty($config['ntpd']['gps']['flag2'])) {
1686
			$ntpcfg .= ' flag2 1';
1687
		}
1688
		if (!empty($config['ntpd']['gps']['flag3'])) {
1689
			$ntpcfg .= ' flag3 1';
1690
		} else {
1691
			$ntpcfg .= ' flag3 0';
1692
		}
1693
		if (!empty($config['ntpd']['gps']['flag4'])) {
1694
			$ntpcfg .= ' flag4 1';
1695
		}
1696
		if (!empty($config['ntpd']['gps']['refid'])) {
1697
			$ntpcfg .= ' refid ';
1698
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1699
		}
1700
		if (!empty($config['ntpd']['gps']['stratum'])) {
1701
			$ntpcfg .= ' stratum ';
1702
			$ntpcfg .= $config['ntpd']['gps']['stratum'];
1703
		}
1704
		$ntpcfg .= "\n";
1705
	} elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
1706
	    file_exists('/dev/'.$config['ntpd']['gpsport']) &&
1707
	    system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1708
		/* This handles a 2.1 and earlier config */
1709
		$ntpcfg .= "# GPS Setup\n";
1710
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1711
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1712
		// Fall back to local clock if GPS is out of sync?
1713
		$ntpcfg .= "server 127.127.1.0\n";
1714
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1715
	}
1716
	/* End GPS configuration */
1717

    
1718
	$ntpcfg .= "\n\n# Upstream Servers\n";
1719
	/* foreach through ntp servers and write out to ntpd.conf */
1720
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1721
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1722
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1723
			$ntpcfg .= ' prefer';
1724
		}
1725
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1726
			$ntpcfg .= ' noselect';
1727
		}
1728
		$ntpcfg .= "\n";
1729
	}
1730
	unset($ts);
1731

    
1732
	$ntpcfg .= "\n\n";
1733
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1734
		$ntpcfg .= "enable stats\n";
1735
		$ntpcfg .= 'statistics';
1736
		if (!empty($config['ntpd']['clockstats'])) {
1737
			$ntpcfg .= ' clockstats';
1738
		}
1739
		if (!empty($config['ntpd']['loopstats'])) {
1740
			$ntpcfg .= ' loopstats';
1741
		}
1742
		if (!empty($config['ntpd']['peerstats'])) {
1743
			$ntpcfg .= ' peerstats';
1744
		}
1745
		$ntpcfg .= "\n";
1746
	}
1747
	$ntpcfg .= "statsdir {$statsdir}\n";
1748
	$ntpcfg .= 'logconfig =syncall +clockall';
1749
	if (!empty($config['ntpd']['logpeer'])) {
1750
		$ntpcfg .= ' +peerall';
1751
	}
1752
	if (!empty($config['ntpd']['logsys'])) {
1753
		$ntpcfg .= ' +sysall';
1754
	}
1755
	$ntpcfg .= "\n";
1756
	$ntpcfg .= "driftfile {$driftfile}\n";
1757

    
1758
	/* Default Access restrictions */
1759
	$ntpcfg .= 'restrict default';
1760
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1761
		$ntpcfg .= ' kod limited';
1762
	}
1763
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1764
		$ntpcfg .= ' nomodify';
1765
	}
1766
	if (!empty($config['ntpd']['noquery'])) {
1767
		$ntpcfg .= ' noquery';
1768
	}
1769
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1770
		$ntpcfg .= ' nopeer';
1771
	}
1772
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1773
		$ntpcfg .= ' notrap';
1774
	}
1775
	if (!empty($config['ntpd']['noserve'])) {
1776
		$ntpcfg .= ' noserve';
1777
	}
1778
	$ntpcfg .= "\nrestrict -6 default";
1779
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1780
		$ntpcfg .= ' kod limited';
1781
	}
1782
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1783
		$ntpcfg .= ' nomodify';
1784
	}
1785
	if (!empty($config['ntpd']['noquery'])) {
1786
		$ntpcfg .= ' noquery';
1787
	}
1788
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1789
		$ntpcfg .= ' nopeer';
1790
	}
1791
	if (!empty($config['ntpd']['noserve'])) {
1792
		$ntpcfg .= ' noserve';
1793
	}
1794
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1795
		$ntpcfg .= ' notrap';
1796
	}
1797
	/* Custom Access Restrictions */
1798
	if (is_array($config['ntpd']['restrictions']) && is_array($config['ntpd']['restrictions']['row'])) {
1799
		$networkacl = $config['ntpd']['restrictions']['row'];
1800
		foreach ($networkacl as $acl) {
1801
			$ntpcfg .= "\nrestrict ";
1802
			if (is_ipaddrv6($acl['acl_network'])) {
1803
				$ntpcfg .= "-6 {$acl['acl_network']} mask " . gen_subnet_mask_v6($acl['mask']) . " ";
1804
			} elseif (is_ipaddrv4($acl['acl_network'])) {
1805
				$ntpcfg .= "{$acl['acl_network']} mask " . gen_subnet_mask($acl['mask']) . " ";
1806
			} else {
1807
				continue;
1808
			}
1809
			if (!empty($acl['kod'])) {
1810
				$ntpcfg .= ' kod limited';
1811
			}
1812
			if (!empty($acl['nomodify'])) {
1813
				$ntpcfg .= ' nomodify';
1814
			}
1815
			if (!empty($acl['noquery'])) {
1816
				$ntpcfg .= ' noquery';
1817
			}
1818
			if (!empty($acl['nopeer'])) {
1819
				$ntpcfg .= ' nopeer';
1820
			}
1821
			if (!empty($acl['noserve'])) {
1822
				$ntpcfg .= ' noserve';
1823
			}
1824
			if (!empty($acl['notrap'])) {
1825
				$ntpcfg .= ' notrap';
1826
			}
1827
		}
1828
	}
1829
	$ntpcfg .= "\n";
1830
	/* End Custom Access Restrictions */
1831

    
1832
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1833
	$ntpcfg .= "\n";
1834
	if (!empty($config['ntpd']['leapsec'])) {
1835
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1836
		file_put_contents('/var/db/leap-seconds', $leapsec);
1837
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1838
	}
1839

    
1840

    
1841
	if (empty($config['ntpd']['interface'])) {
1842
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1843
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1844
		} else {
1845
			$interfaces = array();
1846
		}
1847
	} else {
1848
		$interfaces = explode(",", $config['ntpd']['interface']);
1849
	}
1850

    
1851
	if (is_array($interfaces) && count($interfaces)) {
1852
		$finterfaces = array();
1853
		$ntpcfg .= "interface ignore all\n";
1854
		foreach ($interfaces as $interface) {
1855
			$interface = get_real_interface($interface);
1856
			if (!empty($interface)) {
1857
				$finterfaces[] = $interface;
1858
			}
1859
		}
1860
		foreach ($finterfaces as $interface) {
1861
			$ntpcfg .= "interface listen {$interface}\n";
1862
		}
1863
	}
1864

    
1865
	/* open configuration for writing or bail */
1866
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1867
		log_error(sprintf(gettext("Could not open %s/ntpd.conf for writing"), $g['varetc_path']));
1868
		return;
1869
	}
1870

    
1871
	/* At bootup we just want to write out the config. */
1872
	if (!$start_ntpd) {
1873
		return;
1874
	}
1875

    
1876
	/* if ntpd is running, kill it */
1877
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1878
		killbypid("{$g['varrun_path']}/ntpd.pid");
1879
	}
1880
	@unlink("{$g['varrun_path']}/ntpd.pid");
1881

    
1882
	/* if /var/empty does not exist, create it */
1883
	if (!is_dir("/var/empty")) {
1884
		mkdir("/var/empty", 0775, true);
1885
	}
1886

    
1887
	/* start opentpd, set time now and use /var/etc/ntpd.conf */
1888
	mwexec("/usr/local/sbin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
1889

    
1890
	// Note that we are starting up
1891
	log_error("NTPD is starting up.");
1892
	return;
1893
}
1894

    
1895
function system_halt() {
1896
	global $g;
1897

    
1898
	system_reboot_cleanup();
1899

    
1900
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1901
}
1902

    
1903
function system_reboot() {
1904
	global $g;
1905

    
1906
	system_reboot_cleanup();
1907

    
1908
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1909
}
1910

    
1911
function system_reboot_sync() {
1912
	global $g;
1913

    
1914
	system_reboot_cleanup();
1915

    
1916
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1917
}
1918

    
1919
function system_reboot_cleanup() {
1920
	global $config, $cpzone;
1921

    
1922
	mwexec("/usr/local/bin/beep.sh stop");
1923
	require_once("captiveportal.inc");
1924
	if (is_array($config['captiveportal'])) {
1925
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1926
			captiveportal_radius_stop_all();
1927
			captiveportal_send_server_accounting(true);
1928
		}
1929
	}
1930
	require_once("voucher.inc");
1931
	voucher_save_db_to_config();
1932
	require_once("pkg-utils.inc");
1933
	stop_packages();
1934
}
1935

    
1936
function system_do_shell_commands($early = 0) {
1937
	global $config, $g;
1938
	if (isset($config['system']['developerspew'])) {
1939
		$mt = microtime();
1940
		echo "system_do_shell_commands() being called $mt\n";
1941
	}
1942

    
1943
	if ($early) {
1944
		$cmdn = "earlyshellcmd";
1945
	} else {
1946
		$cmdn = "shellcmd";
1947
	}
1948

    
1949
	if (is_array($config['system'][$cmdn])) {
1950

    
1951
		/* *cmd is an array, loop through */
1952
		foreach ($config['system'][$cmdn] as $cmd) {
1953
			exec($cmd);
1954
		}
1955

    
1956
	} elseif ($config['system'][$cmdn] <> "") {
1957

    
1958
		/* execute single item */
1959
		exec($config['system'][$cmdn]);
1960

    
1961
	}
1962
}
1963

    
1964
function system_console_configure() {
1965
	global $config, $g;
1966
	if (isset($config['system']['developerspew'])) {
1967
		$mt = microtime();
1968
		echo "system_console_configure() being called $mt\n";
1969
	}
1970

    
1971
	if (isset($config['system']['disableconsolemenu'])) {
1972
		touch("{$g['varetc_path']}/disableconsole");
1973
	} else {
1974
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1975
	}
1976
}
1977

    
1978
function system_dmesg_save() {
1979
	global $g;
1980
	if (isset($config['system']['developerspew'])) {
1981
		$mt = microtime();
1982
		echo "system_dmesg_save() being called $mt\n";
1983
	}
1984

    
1985
	$dmesg = "";
1986
	$_gb = exec("/sbin/dmesg", $dmesg);
1987

    
1988
	/* find last copyright line (output from previous boots may be present) */
1989
	$lastcpline = 0;
1990

    
1991
	for ($i = 0; $i < count($dmesg); $i++) {
1992
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
1993
			$lastcpline = $i;
1994
		}
1995
	}
1996

    
1997
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1998
	if (!$fd) {
1999
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
2000
		return 1;
2001
	}
2002

    
2003
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
2004
		fwrite($fd, $dmesg[$i] . "\n");
2005
	}
2006

    
2007
	fclose($fd);
2008
	unset($dmesg);
2009

    
2010
	return 0;
2011
}
2012

    
2013
function system_set_harddisk_standby() {
2014
	global $g, $config;
2015

    
2016
	if (isset($config['system']['developerspew'])) {
2017
		$mt = microtime();
2018
		echo "system_set_harddisk_standby() being called $mt\n";
2019
	}
2020

    
2021
	if (isset($config['system']['harddiskstandby'])) {
2022
		if (platform_booting()) {
2023
			echo gettext('Setting hard disk standby... ');
2024
		}
2025

    
2026
		$standby = $config['system']['harddiskstandby'];
2027
		// Check for a numeric value
2028
		if (is_numeric($standby)) {
2029
			// Get only suitable candidates for standby; using get_smart_drive_list()
2030
			// from utils.inc to get the list of drives.
2031
			$harddisks = get_smart_drive_list();
2032

    
2033
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
2034
			// just in case of some weird pfSense platform installs.
2035
			if (count($harddisks) > 0) {
2036
				// Iterate disks and run the camcontrol command for each
2037
				foreach ($harddisks as $harddisk) {
2038
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
2039
				}
2040
				if (platform_booting()) {
2041
					echo gettext("done.") . "\n";
2042
				}
2043
			} else if (platform_booting()) {
2044
				echo gettext("failed!") . "\n";
2045
			}
2046
		} else if (platform_booting()) {
2047
			echo gettext("failed!") . "\n";
2048
		}
2049
	}
2050
}
2051

    
2052
function system_setup_sysctl() {
2053
	global $config;
2054
	if (isset($config['system']['developerspew'])) {
2055
		$mt = microtime();
2056
		echo "system_setup_sysctl() being called $mt\n";
2057
	}
2058

    
2059
	activate_sysctls();
2060

    
2061
	if (isset($config['system']['sharednet'])) {
2062
		system_disable_arp_wrong_if();
2063
	}
2064
}
2065

    
2066
function system_disable_arp_wrong_if() {
2067
	global $config;
2068
	if (isset($config['system']['developerspew'])) {
2069
		$mt = microtime();
2070
		echo "system_disable_arp_wrong_if() being called $mt\n";
2071
	}
2072
	set_sysctl(array(
2073
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2074
		"net.link.ether.inet.log_arp_movements" => "0"
2075
	));
2076
}
2077

    
2078
function system_enable_arp_wrong_if() {
2079
	global $config;
2080
	if (isset($config['system']['developerspew'])) {
2081
		$mt = microtime();
2082
		echo "system_enable_arp_wrong_if() being called $mt\n";
2083
	}
2084
	set_sysctl(array(
2085
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2086
		"net.link.ether.inet.log_arp_movements" => "1"
2087
	));
2088
}
2089

    
2090
function enable_watchdog() {
2091
	global $config;
2092
	return;
2093
	$install_watchdog = false;
2094
	$supported_watchdogs = array("Geode");
2095
	$file = file_get_contents("/var/log/dmesg.boot");
2096
	foreach ($supported_watchdogs as $sd) {
2097
		if (stristr($file, "Geode")) {
2098
			$install_watchdog = true;
2099
		}
2100
	}
2101
	if ($install_watchdog == true) {
2102
		if (is_process_running("watchdogd")) {
2103
			mwexec("/usr/bin/killall watchdogd", true);
2104
		}
2105
		exec("/usr/sbin/watchdogd");
2106
	}
2107
}
2108

    
2109
function system_check_reset_button() {
2110
	global $g;
2111

    
2112
	$specplatform = system_identify_specific_platform();
2113

    
2114
	switch ($specplatform['name']) {
2115
		case 'alix':
2116
		case 'wrap':
2117
		case 'FW7541':
2118
		case 'APU':
2119
		case 'RCC-VE':
2120
		case 'RCC':
2121
		case 'RCC-DFF':
2122
			break;
2123
		default:
2124
			return 0;
2125
	}
2126

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

    
2129
	if ($retval == 99) {
2130
		/* user has pressed reset button for 2 seconds -
2131
		   reset to factory defaults */
2132
		echo <<<EOD
2133

    
2134
***********************************************************************
2135
* Reset button pressed - resetting configuration to factory defaults. *
2136
* All additional packages installed will be removed                   *
2137
* The system will reboot after this completes.                        *
2138
***********************************************************************
2139

    
2140

    
2141
EOD;
2142

    
2143
		reset_factory_defaults();
2144
		system_reboot_sync();
2145
		exit(0);
2146
	}
2147

    
2148
	return 0;
2149
}
2150

    
2151
function system_get_serial() {
2152
	unset($output);
2153
	$_gb = exec('/bin/kenv smbios.system.serial 2>/dev/null', $output);
2154
	$serial = $output[0];
2155

    
2156
	$vm_guest = get_single_sysctl('kern.vm_guest');
2157

    
2158
	if (strlen($serial) >= 10 && strlen($serial) <= 16 &&
2159
	    $vm_guest == 'none') {
2160
		return $serial;
2161
	}
2162

    
2163
	return get_single_sysctl('kern.hostuuid');
2164
}
2165

    
2166
/*
2167
 * attempt to identify the specific platform (for embedded systems)
2168
 * Returns an array with two elements:
2169
 * name => platform string (e.g. 'wrap', 'alix' etc.)
2170
 * descr => human-readable description (e.g. "PC Engines WRAP")
2171
 */
2172
function system_identify_specific_platform() {
2173
	global $g;
2174

    
2175
	$hw_model = get_single_sysctl('hw.model');
2176

    
2177
	/* Try to guess from smbios strings */
2178
	unset($output);
2179
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2180
	switch ($output[0]) {
2181
		case 'FW7541':
2182
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2183
			break;
2184
		case 'APU':
2185
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2186
			break;
2187
		case 'RCC-VE':
2188
			$result = array();
2189
			$result['name'] = 'RCC-VE';
2190

    
2191
			/* Detect specific models */
2192
			if (!function_exists('does_interface_exist')) {
2193
				require_once("interfaces.inc");
2194
			}
2195
			if (!does_interface_exist('igb4')) {
2196
				$result['model'] = 'SG-2440';
2197
			} elseif (strpos($hw_model, "C2558") !== false) {
2198
				$result['model'] = 'SG-4860';
2199
			} elseif (strpos($hw_model, "C2758") !== false) {
2200
				$result['model'] = 'SG-8860';
2201
			} else {
2202
				$result['model'] = 'RCC-VE';
2203
			}
2204
			$result['descr'] = 'Netgate ' . $result['model'];
2205
			return $result;
2206
			break;
2207
		case 'DFFv2':
2208
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2209
			break;
2210
		case 'RCC':
2211
			return (array('name' => 'RCC', 'descr' => 'Netgate XG-2758'));
2212
			break;
2213
		case 'SYS-5018A-FTN4':
2214
		case 'A1SAi':
2215
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2216
			break;
2217
		case 'SYS-5018D-FN4T':
2218
			return (array('name' => 'XG-1540', 'descr' => 'Super Micro XG-1540'));
2219
			break;
2220
	}
2221

    
2222
	/* the rest of the code only deals with 'embedded' platforms */
2223
	if ($g['platform'] != 'nanobsd') {
2224
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2225
	}
2226

    
2227
	if (strpos($hw_model, "PC Engines WRAP") !== false) {
2228
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2229
	}
2230

    
2231
	if (strpos($hw_model, "PC Engines ALIX") !== false) {
2232
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2233
	}
2234

    
2235
	if (preg_match("/Soekris net45../", $hw_model, $matches)) {
2236
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2237
	}
2238

    
2239
	if (preg_match("/Soekris net48../", $hw_model, $matches)) {
2240
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2241
	}
2242

    
2243
	if (preg_match("/Soekris net55../", $hw_model, $matches)) {
2244
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2245
	}
2246

    
2247
	unset($hw_model);
2248

    
2249
	$dmesg_boot = system_get_dmesg_boot();
2250
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2251
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2252
	}
2253
	unset($dmesg_boot);
2254

    
2255
	/* unknown embedded platform */
2256
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2257
}
2258

    
2259
function system_get_dmesg_boot() {
2260
	global $g;
2261

    
2262
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2263
}
2264

    
2265
?>
(52-52/65)