Project

General

Profile

Download (66.8 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
						if (is_linklocal($gatewayip) == "6" && !strpos($gatewayip, '%')) {
749
							// add interface scope for link local v6 routes
750
							$gatewayip .= "%$interfacegw";
751
						}
752
						mwexec($cmd . escapeshellarg($gatewayip));
753
						if (isset($config['system']['route-debug'])) {
754
							$mt = microtime();
755
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
756
						}
757
					} else if (!empty($interfacegw)) {
758
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
759
						if (isset($config['system']['route-debug'])) {
760
							$mt = microtime();
761
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
762
						}
763
					}
764
				}
765
			}
766
		}
767
		unset($gateways_arr);
768
	}
769
	unset($static_routes);
770

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

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

    
794
	return 0;
795
}
796

    
797
function system_routing_enable() {
798
	global $config, $g;
799
	if (isset($config['system']['developerspew'])) {
800
		$mt = microtime();
801
		echo "system_routing_enable() being called $mt\n";
802
	}
803

    
804
	set_sysctl(array(
805
		"net.inet.ip.forwarding" => "1",
806
		"net.inet6.ip6.forwarding" => "1"
807
	));
808

    
809
	return;
810
}
811

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

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

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

    
859
function clear_all_log_files($restart = false) {
860
	global $g;
861
	exec("/usr/bin/killall syslogd");
862

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

    
868
	if ($restart) {
869
		system_syslogd_start();
870
		killbyname("dhcpd");
871
		services_dhcpd_configure();
872
	}
873
	return;
874
}
875

    
876
function system_syslogd_start() {
877
	global $config, $g;
878
	if (isset($config['system']['developerspew'])) {
879
		$mt = microtime();
880
		echo "system_syslogd_start() being called $mt\n";
881
	}
882

    
883
	mwexec("/etc/rc.d/hostid start");
884

    
885
	$syslogcfg = $config['syslog'];
886

    
887
	if (platform_booting()) {
888
		echo gettext("Starting syslog...");
889
	}
890

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

    
902
	$syslogd_extra = "";
903
	if (isset($syslogcfg)) {
904
		$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');
905
		$syslogconf = "";
906
		if ($config['installedpackages']['package']) {
907
			foreach ($config['installedpackages']['package'] as $package) {
908
				if ($package['logging']) {
909
					array_push($separatelogfacilities, $package['logging']['facilityname']);
910
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
911
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
912
					}
913
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
914
				}
915
			}
916
		}
917
		$facilitylist = implode(',', array_unique($separatelogfacilities));
918
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
919
		if (!isset($syslogcfg['disablelocallogging'])) {
920
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
921
		}
922

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

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

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

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

    
943
		$syslogconf .= "!l2tps\n";
944
		if (!isset($syslogcfg['disablelocallogging'])) {
945
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
946
		}
947

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

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

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

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

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

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

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

    
1001
		$syslogconf .= "!filterlog\n";
1002
		if (!isset($syslogcfg['disablelocallogging'])) {
1003
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
1004
		}
1005

    
1006
		if (isset($syslogcfg['filter'])) {
1007
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1008
		}
1009

    
1010
		$syslogconf .= "!-{$facilitylist}\n";
1011
		if (!isset($syslogcfg['disablelocallogging'])) {
1012
			$syslogconf .= <<<EOD
1013
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
1014
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
1015
local5.*							{$log_directive}{$g['varlog_path']}/nginx.log
1016
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
1017
*.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
1018
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
1019
*.emerg								*
1020

    
1021
EOD;
1022
		}
1023
		if (isset($syslogcfg['vpn'])) {
1024
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
1025
		}
1026
		if (isset($syslogcfg['portalauth'])) {
1027
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
1028
		}
1029
		if (isset($syslogcfg['dhcp'])) {
1030
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
1031
		}
1032
		if (isset($syslogcfg['system'])) {
1033
			$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");
1034
		}
1035
		if (isset($syslogcfg['logall'])) {
1036
			// Make everything mean everything, including facilities excluded above.
1037
			$syslogconf .= "!*\n";
1038
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1039
		}
1040

    
1041
		if (isset($syslogcfg['zmqserver'])) {
1042
				$syslogconf .= <<<EOD
1043
*.*								^{$syslogcfg['zmqserver']}
1044

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

    
1055
		// Ensure that the log directory exists
1056
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
1057
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
1058
		}
1059

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

    
1078
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1079
	}
1080

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

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

    
1092

    
1093
	$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}");
1094

    
1095
	if (platform_booting()) {
1096
		echo gettext("done.") . "\n";
1097
	}
1098

    
1099
	return $retval;
1100
}
1101

    
1102
function system_webgui_create_certificate() {
1103
	global $config, $g;
1104

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

    
1115
	$cert = array();
1116
	$cert['refid'] = uniqid();
1117
	$cert['descr'] = sprintf(gettext("webConfigurator default (%s)"), $cert['refid']);
1118

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

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

    
1142
function system_webgui_start() {
1143
	global $config, $g;
1144

    
1145
	if (platform_booting()) {
1146
		echo gettext("Starting webConfigurator...");
1147
	}
1148

    
1149
	chdir($g['www_path']);
1150

    
1151
	/* defaults */
1152
	$portarg = "80";
1153
	$crt = "";
1154
	$key = "";
1155
	$ca = "";
1156

    
1157
	/* non-standard port? */
1158
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1159
		$portarg = "{$config['system']['webgui']['port']}";
1160
	}
1161

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

    
1171
		if (!$config['system']['webgui']['port']) {
1172
			$portarg = "443";
1173
		}
1174
		$ca = ca_chain($cert);
1175
	}
1176

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

    
1182
	/* kill any running nginx */
1183
	killbypid("{$g['varrun_path']}/nginx-webConfigurator.pid");
1184

    
1185
	sleep(1);
1186

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

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

    
1192
	if (platform_booting()) {
1193
		if ($res == 0) {
1194
			echo gettext("done.") . "\n";
1195
		} else {
1196
			echo gettext("failed!") . "\n";
1197
		}
1198
	}
1199

    
1200
	return $res;
1201
}
1202

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

    
1214
	global $config, $g;
1215

    
1216
	if (isset($config['system']['developerspew'])) {
1217
		$mt = microtime();
1218
		echo "system_generate_nginx_config() being called $mt\n";
1219
	}
1220

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

    
1242
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1243
		if (empty($maxprocperip)) {
1244
			$maxprocperip = 10;
1245
		}
1246
		$captive_portal_maxprocperip = "\t\tlimit_conn addr $maxprocperip;\n";
1247
	}
1248

    
1249
	if (empty($port)) {
1250
		$nginx_port = "80";
1251
	} else {
1252
		$nginx_port = $port;
1253
	}
1254

    
1255
	$memory = get_memory();
1256
	$realmem = $memory[1];
1257

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

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

    
1276
	$nginx_config = <<<EOD
1277
#
1278
# nginx configuration file
1279

    
1280
pid {$g['varrun_path']}/{$pid_file};
1281

    
1282
user  root wheel;
1283
worker_processes  {$max_procs};
1284

    
1285
EOD;
1286

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

    
1291
	$nginx_config .= <<<EOD
1292

    
1293
events {
1294
    worker_connections  1024;
1295
}
1296

    
1297
http {
1298
	include       /usr/local/etc/nginx/mime.types;
1299
	default_type  application/octet-stream;
1300
	add_header X-Frame-Options SAMEORIGIN;
1301
	server_tokens off;
1302

    
1303
	sendfile        on;
1304

    
1305
	access_log      syslog:server=unix:/var/run/log,facility=local5 combined;
1306

    
1307
EOD;
1308

    
1309
	if ($captive_portal !== false) {
1310
		$nginx_config .= "\tlimit_conn_zone \$binary_remote_addr zone=addr:10m;\n";
1311
		$nginx_config .= "\tkeepalive_timeout 0;\n";
1312
	} else {
1313
		$nginx_config .= "\tkeepalive_timeout 75;\n";
1314
	}
1315

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

    
1346
	$nginx_config .= <<<EOD
1347

    
1348
		client_max_body_size 200m;
1349

    
1350
		gzip on;
1351
		gzip_types text/plain text/css text/javascript application/x-javascript text/xml application/xml application/xml+rss application/json;
1352

    
1353

    
1354
EOD;
1355

    
1356
	if ($captive_portal !== false) {
1357
		$nginx_config .= <<<EOD
1358
$captive_portal_maxprocperip
1359
$cp_hostcheck
1360
$cp_rewrite
1361
		log_not_found off;
1362

    
1363
EOD;
1364

    
1365
	}
1366

    
1367
	$nginx_config .= <<<EOD
1368
		root "{$document_root}";
1369
		location / {
1370
			index  index.php index.html index.htm;
1371
		}
1372

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

    
1385
EOD;
1386

    
1387
	$cert = str_replace("\r", "", $cert);
1388
	$key = str_replace("\r", "", $key);
1389

    
1390
	$cert = str_replace("\n\n", "\n", $cert);
1391
	$key = str_replace("\n\n", "\n", $key);
1392

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

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

    
1429
EOD;
1430
	}
1431

    
1432
	$nginx_config .= "}\n";
1433

    
1434
	$fd = fopen("{$filename}", "w");
1435
	if (!$fd) {
1436
		printf(gettext("Error: cannot open %s in system_generate_nginx_config().%s"), $filename, "\n");
1437
		return 1;
1438
	}
1439
	fwrite($fd, $nginx_config);
1440
	fclose($fd);
1441

    
1442
	/* nginx will fail to start if this directory does not exist. */
1443
	safe_mkdir("/var/tmp/nginx/");
1444

    
1445
	return 0;
1446

    
1447
}
1448

    
1449
function system_get_timezone_list() {
1450
	global $g;
1451

    
1452
	$file_list = array_merge(
1453
		glob("/usr/share/zoneinfo/[A-Z]*"),
1454
		glob("/usr/share/zoneinfo/*/*"),
1455
		glob("/usr/share/zoneinfo/*/*/*")
1456
	);
1457

    
1458
	if (empty($file_list)) {
1459
		$file_list[] = $g['default_timezone'];
1460
	} else {
1461
		/* Remove directories from list */
1462
		$file_list = array_filter($file_list, function($v) {
1463
			return !is_dir($v);
1464
		});
1465
	}
1466

    
1467
	/* Remove directory prefix */
1468
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1469

    
1470
	sort($file_list);
1471

    
1472
	return $file_list;
1473
}
1474

    
1475
function system_timezone_configure() {
1476
	global $config, $g;
1477
	if (isset($config['system']['developerspew'])) {
1478
		$mt = microtime();
1479
		echo "system_timezone_configure() being called $mt\n";
1480
	}
1481

    
1482
	$syscfg = $config['system'];
1483

    
1484
	if (platform_booting()) {
1485
		echo gettext("Setting timezone...");
1486
	}
1487

    
1488
	/* extract appropriate timezone file */
1489
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1490
	conf_mount_rw();
1491
	/* DO NOT remove \n otherwise tzsetup will fail */
1492
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1493
	mwexec("/usr/sbin/tzsetup -r");
1494
	conf_mount_ro();
1495

    
1496
	if (platform_booting()) {
1497
		echo gettext("done.") . "\n";
1498
	}
1499
}
1500

    
1501
function system_ntp_setup_gps($serialport) {
1502
	global $config, $g;
1503
	$gps_device = '/dev/gps0';
1504
	$serialport = '/dev/'.$serialport;
1505

    
1506
	if (!file_exists($serialport)) {
1507
		return false;
1508
	}
1509

    
1510
	conf_mount_rw();
1511
	// Create symlink that ntpd requires
1512
	unlink_if_exists($gps_device);
1513
	@symlink($serialport, $gps_device);
1514

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

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

    
1539
	/* Send the following to the GPS port to initialize the GPS */
1540
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1541
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1542
	} else {
1543
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1544
	}
1545

    
1546
	/* XXX: Why not file_put_contents to the device */
1547
	@file_put_contents('/tmp/gps.init', $gps_init);
1548
	mwexec("cat /tmp/gps.init > {$serialport}");
1549

    
1550
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1551
	if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
1552
		@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:\n", FILE_APPEND);
1553
	}
1554

    
1555
	conf_mount_ro();
1556

    
1557
	return true;
1558
}
1559

    
1560
function system_ntp_setup_pps($serialport) {
1561
	global $config, $g;
1562

    
1563
	$pps_device = '/dev/pps0';
1564
	$serialport = '/dev/'.$serialport;
1565

    
1566
	if (!file_exists($serialport)) {
1567
		return false;
1568
	}
1569

    
1570
	conf_mount_rw();
1571
	// Create symlink that ntpd requires
1572
	unlink_if_exists($pps_device);
1573
	@symlink($serialport, $pps_device);
1574

    
1575
	conf_mount_ro();
1576

    
1577
	return true;
1578
}
1579

    
1580

    
1581
function system_ntp_configure() {
1582
	global $config, $g;
1583

    
1584
	$driftfile = "/var/db/ntpd.drift";
1585
	$statsdir = "/var/log/ntp";
1586
	$gps_device = '/dev/gps0';
1587

    
1588
	safe_mkdir($statsdir);
1589

    
1590
	if (!is_array($config['ntpd'])) {
1591
		$config['ntpd'] = array();
1592
	}
1593

    
1594
	$ntpcfg = "# \n";
1595
	$ntpcfg .= "# pfSense ntp configuration file \n";
1596
	$ntpcfg .= "# \n\n";
1597
	$ntpcfg .= "tinker panic 0 \n";
1598

    
1599
	/* Add Orphan mode */
1600
	$ntpcfg .= "# Orphan mode stratum\n";
1601
	$ntpcfg .= 'tos orphan ';
1602
	if (!empty($config['ntpd']['orphan'])) {
1603
		$ntpcfg .= $config['ntpd']['orphan'];
1604
	} else {
1605
		$ntpcfg .= '12';
1606
	}
1607
	$ntpcfg .= "\n";
1608

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

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

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

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

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

    
1838
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1839
	$ntpcfg .= "\n";
1840
	if (!empty($config['ntpd']['leapsec'])) {
1841
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1842
		file_put_contents('/var/db/leap-seconds', $leapsec);
1843
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1844
	}
1845

    
1846

    
1847
	if (empty($config['ntpd']['interface'])) {
1848
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1849
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1850
		} else {
1851
			$interfaces = array();
1852
		}
1853
	} else {
1854
		$interfaces = explode(",", $config['ntpd']['interface']);
1855
	}
1856

    
1857
	if (is_array($interfaces) && count($interfaces)) {
1858
		$finterfaces = array();
1859
		$ntpcfg .= "interface ignore all\n";
1860
		foreach ($interfaces as $interface) {
1861
			$interface = get_real_interface($interface);
1862
			if (!empty($interface)) {
1863
				$finterfaces[] = $interface;
1864
			}
1865
		}
1866
		foreach ($finterfaces as $interface) {
1867
			$ntpcfg .= "interface listen {$interface}\n";
1868
		}
1869
	}
1870

    
1871
	/* open configuration for writing or bail */
1872
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1873
		log_error(sprintf(gettext("Could not open %s/ntpd.conf for writing"), $g['varetc_path']));
1874
		return;
1875
	}
1876

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

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

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

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

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

    
1899
	system_reboot_cleanup();
1900

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

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

    
1907
	system_reboot_cleanup();
1908

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

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

    
1915
	system_reboot_cleanup();
1916

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

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

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

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

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

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

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

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

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

    
1962
	}
1963
}
1964

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

    
1972
	$dmesg = "";
1973
	$_gb = exec("/sbin/dmesg", $dmesg);
1974

    
1975
	/* find last copyright line (output from previous boots may be present) */
1976
	$lastcpline = 0;
1977

    
1978
	for ($i = 0; $i < count($dmesg); $i++) {
1979
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
1980
			$lastcpline = $i;
1981
		}
1982
	}
1983

    
1984
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1985
	if (!$fd) {
1986
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1987
		return 1;
1988
	}
1989

    
1990
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
1991
		fwrite($fd, $dmesg[$i] . "\n");
1992
	}
1993

    
1994
	fclose($fd);
1995
	unset($dmesg);
1996

    
1997
	return 0;
1998
}
1999

    
2000
function system_set_harddisk_standby() {
2001
	global $g, $config;
2002

    
2003
	if (isset($config['system']['developerspew'])) {
2004
		$mt = microtime();
2005
		echo "system_set_harddisk_standby() being called $mt\n";
2006
	}
2007

    
2008
	if (isset($config['system']['harddiskstandby'])) {
2009
		if (platform_booting()) {
2010
			echo gettext('Setting hard disk standby... ');
2011
		}
2012

    
2013
		$standby = $config['system']['harddiskstandby'];
2014
		// Check for a numeric value
2015
		if (is_numeric($standby)) {
2016
			// Get only suitable candidates for standby; using get_smart_drive_list()
2017
			// from utils.inc to get the list of drives.
2018
			$harddisks = get_smart_drive_list();
2019

    
2020
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
2021
			// just in case of some weird pfSense platform installs.
2022
			if (count($harddisks) > 0) {
2023
				// Iterate disks and run the camcontrol command for each
2024
				foreach ($harddisks as $harddisk) {
2025
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
2026
				}
2027
				if (platform_booting()) {
2028
					echo gettext("done.") . "\n";
2029
				}
2030
			} else if (platform_booting()) {
2031
				echo gettext("failed!") . "\n";
2032
			}
2033
		} else if (platform_booting()) {
2034
			echo gettext("failed!") . "\n";
2035
		}
2036
	}
2037
}
2038

    
2039
function system_setup_sysctl() {
2040
	global $config;
2041
	if (isset($config['system']['developerspew'])) {
2042
		$mt = microtime();
2043
		echo "system_setup_sysctl() being called $mt\n";
2044
	}
2045

    
2046
	activate_sysctls();
2047

    
2048
	if (isset($config['system']['sharednet'])) {
2049
		system_disable_arp_wrong_if();
2050
	}
2051
}
2052

    
2053
function system_disable_arp_wrong_if() {
2054
	global $config;
2055
	if (isset($config['system']['developerspew'])) {
2056
		$mt = microtime();
2057
		echo "system_disable_arp_wrong_if() being called $mt\n";
2058
	}
2059
	set_sysctl(array(
2060
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2061
		"net.link.ether.inet.log_arp_movements" => "0"
2062
	));
2063
}
2064

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

    
2077
function enable_watchdog() {
2078
	global $config;
2079
	return;
2080
	$install_watchdog = false;
2081
	$supported_watchdogs = array("Geode");
2082
	$file = file_get_contents("/var/log/dmesg.boot");
2083
	foreach ($supported_watchdogs as $sd) {
2084
		if (stristr($file, "Geode")) {
2085
			$install_watchdog = true;
2086
		}
2087
	}
2088
	if ($install_watchdog == true) {
2089
		if (is_process_running("watchdogd")) {
2090
			mwexec("/usr/bin/killall watchdogd", true);
2091
		}
2092
		exec("/usr/sbin/watchdogd");
2093
	}
2094
}
2095

    
2096
function system_check_reset_button() {
2097
	global $g;
2098

    
2099
	$specplatform = system_identify_specific_platform();
2100

    
2101
	switch ($specplatform['name']) {
2102
		case 'alix':
2103
		case 'wrap':
2104
		case 'FW7541':
2105
		case 'APU':
2106
		case 'RCC-VE':
2107
		case 'RCC':
2108
		case 'RCC-DFF':
2109
			break;
2110
		default:
2111
			return 0;
2112
	}
2113

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

    
2116
	if ($retval == 99) {
2117
		/* user has pressed reset button for 2 seconds -
2118
		   reset to factory defaults */
2119
		echo <<<EOD
2120

    
2121
***********************************************************************
2122
* Reset button pressed - resetting configuration to factory defaults. *
2123
* All additional packages installed will be removed                   *
2124
* The system will reboot after this completes.                        *
2125
***********************************************************************
2126

    
2127

    
2128
EOD;
2129

    
2130
		reset_factory_defaults();
2131
		system_reboot_sync();
2132
		exit(0);
2133
	}
2134

    
2135
	return 0;
2136
}
2137

    
2138
function system_get_serial() {
2139
	unset($output);
2140
	$_gb = exec('/bin/kenv smbios.system.serial 2>/dev/null', $output);
2141
	$serial = $output[0];
2142

    
2143
	$vm_guest = get_single_sysctl('kern.vm_guest');
2144

    
2145
	if (strlen($serial) >= 10 && strlen($serial) <= 16 &&
2146
	    $vm_guest == 'none') {
2147
		return $serial;
2148
	}
2149

    
2150
	return get_single_sysctl('kern.hostuuid');
2151
}
2152

    
2153
/*
2154
 * attempt to identify the specific platform (for embedded systems)
2155
 * Returns an array with two elements:
2156
 * name => platform string (e.g. 'wrap', 'alix' etc.)
2157
 * descr => human-readable description (e.g. "PC Engines WRAP")
2158
 */
2159
function system_identify_specific_platform() {
2160
	global $g;
2161

    
2162
	$hw_model = get_single_sysctl('hw.model');
2163

    
2164
	/* Try to guess from smbios strings */
2165
	unset($product);
2166
	unset($maker);
2167
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $product);
2168
	$_gb = exec('/bin/kenv smbios.system.maker 2>/dev/null', $maker);
2169
	switch ($product[0]) {
2170
		case 'FW7541':
2171
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2172
			break;
2173
		case 'APU':
2174
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2175
			break;
2176
		case 'RCC-VE':
2177
			$result = array();
2178
			$result['name'] = 'RCC-VE';
2179

    
2180
			/* Detect specific models */
2181
			if (!function_exists('does_interface_exist')) {
2182
				require_once("interfaces.inc");
2183
			}
2184
			if (!does_interface_exist('igb4')) {
2185
				$result['model'] = 'SG-2440';
2186
			} elseif (strpos($hw_model, "C2558") !== false) {
2187
				$result['model'] = 'SG-4860';
2188
			} elseif (strpos($hw_model, "C2758") !== false) {
2189
				$result['model'] = 'SG-8860';
2190
			} else {
2191
				$result['model'] = 'RCC-VE';
2192
			}
2193
			$result['descr'] = 'Netgate ' . $result['model'];
2194
			return $result;
2195
			break;
2196
		case 'DFFv2':
2197
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2198
			break;
2199
		case 'RCC':
2200
			return (array('name' => 'RCC', 'descr' => 'Netgate XG-2758'));
2201
			break;
2202
		case 'SYS-5018A-FTN4':
2203
		case 'A1SAi':
2204
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2205
			break;
2206
		case 'SYS-5018D-FN4T':
2207
			return (array('name' => 'XG-1540', 'descr' => 'Super Micro XG-1540'));
2208
			break;
2209
		case 'Virtual Machine':
2210
			if ($maker[0] == "Microsoft Corporation") {
2211
				return (array('name' => 'Hyper-V', 'descr' => 'Hyper-V Virtual Machine'));
2212
			}
2213
			break;
2214
	}
2215

    
2216
	/* the rest of the code only deals with 'embedded' platforms */
2217
	if ($g['platform'] != 'nanobsd') {
2218
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2219
	}
2220

    
2221
	if (strpos($hw_model, "PC Engines WRAP") !== false) {
2222
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2223
	}
2224

    
2225
	if (strpos($hw_model, "PC Engines ALIX") !== false) {
2226
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2227
	}
2228

    
2229
	if (preg_match("/Soekris net45../", $hw_model, $matches)) {
2230
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2231
	}
2232

    
2233
	if (preg_match("/Soekris net48../", $hw_model, $matches)) {
2234
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2235
	}
2236

    
2237
	if (preg_match("/Soekris net55../", $hw_model, $matches)) {
2238
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2239
	}
2240

    
2241
	unset($hw_model);
2242

    
2243
	$dmesg_boot = system_get_dmesg_boot();
2244
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2245
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2246
	}
2247
	unset($dmesg_boot);
2248

    
2249
	/* unknown embedded platform */
2250
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2251
}
2252

    
2253
function system_get_dmesg_boot() {
2254
	global $g;
2255

    
2256
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2257
}
2258

    
2259
?>
(52-52/65)