Project

General

Profile

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

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

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

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

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

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

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

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

    
55
		$ac_mode = "hadp";
56
		if (!empty($config['system']['powerd_ac_mode'])) {
57
			$ac_mode = $config['system']['powerd_ac_mode'];
58
		}
59

    
60
		$battery_mode = "hadp";
61
		if (!empty($config['system']['powerd_battery_mode'])) {
62
			$battery_mode = $config['system']['powerd_battery_mode'];
63
		}
64

    
65
		$normal_mode = "hadp";
66
		if (!empty($config['system']['powerd_normal_mode'])) {
67
			$normal_mode = $config['system']['powerd_normal_mode'];
68
		}
69

    
70
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
71
	}
72
}
73

    
74
function get_default_sysctl_value($id) {
75
	global $sysctls;
76

    
77
	if (isset($sysctls[$id])) {
78
		return $sysctls[$id];
79
	}
80
}
81

    
82
function get_sysctl_descr($sysctl) {
83
	unset($output);
84
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
85

    
86
	return $output[0];
87
}
88

    
89
function system_get_sysctls() {
90
	global $config, $sysctls;
91

    
92
	$disp_sysctl = array();
93
	$disp_cache = array();
94
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
95
		foreach ($config['sysctl']['item'] as $id => $tunable) {
96
			if ($tunable['value'] == "default") {
97
				$value = get_default_sysctl_value($tunable['tunable']);
98
			} else {
99
				$value = $tunable['value'];
100
			}
101

    
102
			$disp_sysctl[$id] = $tunable;
103
			$disp_sysctl[$id]['modified'] = true;
104
			$disp_cache[$tunable['tunable']] = 'set';
105
		}
106
	}
107

    
108
	foreach ($sysctls as $sysctl => $value) {
109
		if (isset($disp_cache[$sysctl])) {
110
			continue;
111
		}
112

    
113
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
114
	}
115
	unset($disp_cache);
116
	return $disp_sysctl;
117
}
118

    
119
function activate_sysctls() {
120
	global $config, $g, $sysctls;
121

    
122
	if ($g['platform'] == 'jail') {
123
		return;
124
	}
125

    
126
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
127
		foreach ($config['sysctl']['item'] as $tunable) {
128
			if ($tunable['value'] == "default") {
129
				$value = get_default_sysctl_value($tunable['tunable']);
130
			} else {
131
				$value = $tunable['value'];
132
			}
133

    
134
			$sysctls[$tunable['tunable']] = $value;
135
		}
136
	}
137

    
138
	set_sysctl($sysctls);
139
}
140

    
141
function system_resolvconf_generate($dynupdate = false) {
142
	global $config, $g;
143

    
144
	if (isset($config['system']['developerspew'])) {
145
		$mt = microtime();
146
		echo "system_resolvconf_generate() being called $mt\n";
147
	}
148

    
149
	$syscfg = $config['system'];
150

    
151
	if ((((isset($config['dnsmasq']['enable'])) &&
152
	      (!isset($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
153
	      (empty($config['dnsmasq']['interface']) ||
154
	       in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
155
	     ((isset($config['unbound']['enable'])) &&
156
	      (!isset($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
157
	      (empty($config['unbound']['active_interface']) ||
158
	       in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
159
	       in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
160
	     (!isset($config['system']['dnslocalhost']))) {
161
		$resolvconf .= "nameserver 127.0.0.1\n";
162
	}
163

    
164
	if (isset($syscfg['dnsallowoverride'])) {
165
		/* get dynamically assigned DNS servers (if any) */
166
		$ns = array_unique(get_searchdomains());
167
		foreach ($ns as $searchserver) {
168
			if ($searchserver) {
169
				$resolvconf .= "search {$searchserver}\n";
170
			}
171
		}
172
		$ns = array_unique(get_nameservers());
173
		foreach ($ns as $nameserver) {
174
			if ($nameserver) {
175
				$resolvconf .= "nameserver $nameserver\n";
176
			}
177
		}
178
	} else {
179
		// Do not create blank search/domain lines, it can break tools like dig.
180
		if ($syscfg['domain']) {
181
			$resolvconf .= "search {$syscfg['domain']}\n";
182
		}
183
	}
184
	if (is_array($syscfg['dnsserver'])) {
185
		foreach ($syscfg['dnsserver'] as $ns) {
186
			if ($ns) {
187
				$resolvconf .= "nameserver $ns\n";
188
			}
189
		}
190
	}
191

    
192
	// Add EDNS support
193
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
194
		$resolvconf .= "options edns0\n";
195
	}
196

    
197
	$dnslock = lock('resolvconf', LOCK_EX);
198

    
199
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
200
	if (!$fd) {
201
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
202
		unlock($dnslock);
203
		return 1;
204
	}
205

    
206
	fwrite($fd, $resolvconf);
207
	fclose($fd);
208

    
209
	// Prevent resolvconf(8) from rewriting our resolv.conf
210
	$fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
211
	if (!$fd) {
212
		printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
213
		return 1;
214
	}
215
	fwrite($fd, "resolv_conf=\"/dev/null\"\n");
216
	fclose($fd);
217

    
218
	if (!platform_booting()) {
219
		/* restart dhcpd (nameservers may have changed) */
220
		if (!$dynupdate) {
221
			services_dhcpd_configure();
222
		}
223
	}
224

    
225
	/* setup static routes for DNS servers. */
226
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
227
		/* setup static routes for dns servers */
228
		$dnsgw = "dns{$dnscounter}gw";
229
		if (isset($config['system'][$dnsgw])) {
230
			$gwname = $config['system'][$dnsgw];
231
			if (($gwname <> "") && ($gwname <> "none")) {
232
				$gatewayip = lookup_gateway_ip_by_name($gwname);
233
				if (is_ipaddrv4($gatewayip)) {
234
					/* dns server array starts at 0 */
235
					$dnscountermo = $dnscounter - 1;
236
					mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
237
					if (isset($config['system']['route-debug'])) {
238
						$mt = microtime();
239
						log_error("ROUTING debug: $mt - route change -host {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
240
					}
241
				}
242
				if (is_ipaddrv6($gatewayip)) {
243
					/* dns server array starts at 0 */
244
					$dnscountermo = $dnscounter - 1;
245
					mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
246
					if (isset($config['system']['route-debug'])) {
247
						$mt = microtime();
248
						log_error("ROUTING debug: $mt - route change -host -inet6 {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
249
					}
250
				}
251
			}
252
		}
253
	}
254

    
255
	unlock($dnslock);
256

    
257
	return 0;
258
}
259

    
260
function get_searchdomains() {
261
	global $config, $g;
262

    
263
	$master_list = array();
264

    
265
	// Read in dhclient nameservers
266
	$search_list = glob("/var/etc/searchdomain_*");
267
	if (is_array($search_list)) {
268
		foreach ($search_list as $fdns) {
269
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
270
			if (!is_array($contents)) {
271
				continue;
272
			}
273
			foreach ($contents as $dns) {
274
				if (is_hostname($dns)) {
275
					$master_list[] = $dns;
276
				}
277
			}
278
		}
279
	}
280

    
281
	return $master_list;
282
}
283

    
284
function get_nameservers() {
285
	global $config, $g;
286
	$master_list = array();
287

    
288
	// Read in dhclient nameservers
289
	$dns_lists = glob("/var/etc/nameserver_*");
290
	if (is_array($dns_lists)) {
291
		foreach ($dns_lists as $fdns) {
292
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
293
			if (!is_array($contents)) {
294
				continue;
295
			}
296
			foreach ($contents as $dns) {
297
				if (is_ipaddr($dns)) {
298
					$master_list[] = $dns;
299
				}
300
			}
301
		}
302
	}
303

    
304
	// Read in any extra nameservers
305
	if (file_exists("/var/etc/nameservers.conf")) {
306
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
307
		if (is_array($dns_s)) {
308
			foreach ($dns_s as $dns) {
309
				if (is_ipaddr($dns)) {
310
					$master_list[] = $dns;
311
				}
312
			}
313
		}
314
	}
315

    
316
	return $master_list;
317
}
318

    
319
function system_hosts_generate() {
320
	global $config, $g;
321
	if (isset($config['system']['developerspew'])) {
322
		$mt = microtime();
323
		echo "system_hosts_generate() being called $mt\n";
324
	}
325

    
326
	$syscfg = $config['system'];
327
	if (isset($config['unbound']) && isset($config['unbound']['enable'])) {
328
		$dnsmasqcfg = $config['unbound'];
329
	} else {
330
		$dnsmasqcfg = $config['dnsmasq'];
331
	}
332

    
333
	$hosts =  "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
334
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
335
	$lhosts = "";
336
	$dhosts = "";
337

    
338
	if ($config['interfaces']['lan']) {
339
		$cfgip = get_interface_ip("lan");
340
		if (is_ipaddr($cfgip)) {
341
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
342
		}
343
		$cfgipv6 = get_interface_ipv6("lan");
344
		if (is_ipaddrv6($cfgipv6)) {
345
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
346
		}
347
	} else {
348
		$sysiflist = get_configured_interface_list();
349
		$hosts_if_found = false;
350
		foreach ($sysiflist as $sysif) {
351
			if (!interface_has_gateway($sysif)) {
352
				$cfgip = get_interface_ip($sysif);
353
				if (is_ipaddr($cfgip)) {
354
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
355
					$hosts_if_found = true;
356
				}
357
				$cfgipv6 = get_interface_ipv6($sysif);
358
				if (is_ipaddrv6($cfgipv6)) {
359
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
360
					$hosts_if_found = true;
361
				}
362
				if ($hosts_if_found == true) {
363
					break;
364
				}
365
			}
366
		}
367
	}
368

    
369
	if (isset($dnsmasqcfg['enable'])) {
370
		if (!is_array($dnsmasqcfg['hosts'])) {
371
			$dnsmasqcfg['hosts'] = array();
372
		}
373

    
374
		foreach ($dnsmasqcfg['hosts'] as $host) {
375
			if ($host['host']) {
376
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
377
			} else {
378
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
379
			}
380
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item'])) {
381
				continue;
382
			}
383
			foreach ($host['aliases']['item'] as $alias) {
384
				if ($alias['host']) {
385
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
386
				} else {
387
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
388
				}
389
			}
390
		}
391
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
392
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
393
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
394
					foreach ($dhcpifconf['staticmap'] as $host) {
395
						if ($host['ipaddr'] && $host['hostname'] && $host['domain']) {
396
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
397
						} else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain']) {
398
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
399
						} else if ($host['ipaddr'] && $host['hostname']) {
400
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
401
						}
402
					}
403
				}
404
			}
405
		}
406
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
407
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
408
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
409
					foreach ($dhcpifconf['staticmap'] as $host) {
410
						if ($host['ipaddrv6'] && $host['hostname'] && $host['domain']) {
411
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
412
						} else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain']) {
413
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
414
						} else if ($host['ipaddrv6'] && $host['hostname']) {
415
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
416
						}
417
					}
418
				}
419
			}
420
		}
421

    
422
		if (isset($dnsmasqcfg['dhcpfirst'])) {
423
			$hosts .= $dhosts . $lhosts;
424
		} else {
425
			$hosts .= $lhosts . $dhosts;
426
		}
427
	}
428

    
429
	/*
430
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be
431
	 * killed before writing to hosts files.
432
	 */
433
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
434
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
435
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
436
	}
437
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
438
	if (!$fd) {
439
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
440
		return 1;
441
	}
442
	fwrite($fd, $hosts);
443
	fclose($fd);
444

    
445
	if (isset($config['unbound']['enable'])) {
446
		require_once("unbound.inc");
447
		unbound_hosts_generate();
448
	}
449

    
450
	return 0;
451
}
452

    
453
function system_dhcpleases_configure() {
454
	global $config, $g;
455

    
456
	if ($g['platform'] == 'jail') {
457
		return;
458
	}
459
	/* Start the monitoring process for dynamic dhcpclients. */
460
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
461
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
462
		/* Make sure we do not error out */
463
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
464
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
465
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
466
		}
467

    
468
		if (isset($config['unbound']['enable'])) {
469
			$dns_pid = "unbound.pid";
470
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
471
		} else {
472
			$dns_pid = "dnsmasq.pid";
473
			$unbound_conf = "";
474
		}
475

    
476
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
477
		if (isvalidpid($pidfile)) {
478
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
479
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
480
			if (intval($retval) == 0) {
481
				sigkillbypid($pidfile, "HUP");
482
				return;
483
			} else {
484
				sigkillbypid($pidfile, "TERM");
485
			}
486
		}
487

    
488
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
489
		if (is_process_running("dhcpleases")) {
490
			sigkillbyname('dhcpleases', "TERM");
491
		}
492
		@unlink($pidfile);
493
		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");
494
	} else {
495
		sigkillbypid($pidfile, "TERM");
496
		@unlink($pidfile);
497
	}
498
}
499

    
500
function system_hostname_configure() {
501
	global $config, $g;
502
	if (isset($config['system']['developerspew'])) {
503
		$mt = microtime();
504
		echo "system_hostname_configure() being called $mt\n";
505
	}
506

    
507
	$syscfg = $config['system'];
508

    
509
	/* set hostname */
510
	$status = mwexec("/bin/hostname " .
511
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
512

    
513
	/* Setup host GUID ID.  This is used by ZFS. */
514
	mwexec("/etc/rc.d/hostid start");
515

    
516
	return $status;
517
}
518

    
519
function system_routing_configure($interface = "") {
520
	global $config, $g;
521
	if ($g['platform'] == 'jail') {
522
		return;
523
	}
524
	if (isset($config['system']['developerspew'])) {
525
		$mt = microtime();
526
		echo "system_routing_configure() being called $mt\n";
527
	}
528

    
529
	$gatewayip = "";
530
	$interfacegw = "";
531
	$gatewayipv6 = "";
532
	$interfacegwv6 = "";
533
	$foundgw = false;
534
	$foundgwv6 = false;
535
	/* tack on all the hard defined gateways as well */
536
	if (is_array($config['gateways']['gateway_item'])) {
537
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
538
		foreach	($config['gateways']['gateway_item'] as $gateway) {
539
			if (isset($gateway['defaultgw'])) {
540
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
541
					if (strpos($gateway['gateway'], ":")) {
542
						continue;
543
					}
544
					if ($gateway['gateway'] == "dynamic") {
545
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
546
					}
547
					$gatewayip = $gateway['gateway'];
548
					$interfacegw = $gateway['interface'];
549
					if (!empty($gateway['interface'])) {
550
						$defaultif = get_real_interface($gateway['interface']);
551
						if ($defaultif) {
552
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
553
						}
554
					}
555
					$foundgw = true;
556
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
557
					if ($gateway['gateway'] == "dynamic") {
558
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
559
					}
560
					$gatewayipv6 = $gateway['gateway'];
561
					$interfacegwv6 = $gateway['interface'];
562
					if (!empty($gateway['interface'])) {
563
						$defaultifv6 = get_real_interface($gateway['interface']);
564
						if ($defaultifv6) {
565
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
566
						}
567
					}
568
					$foundgwv6 = true;
569
				}
570
			}
571
			if ($foundgw === true && $foundgwv6 === true) {
572
				break;
573
			}
574
		}
575
	}
576
	if ($foundgw == false) {
577
		$defaultif = get_real_interface("wan");
578
		$interfacegw = "wan";
579
		$gatewayip = get_interface_gateway("wan");
580
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
581
	}
582
	if ($foundgwv6 == false) {
583
		$defaultifv6 = get_real_interface("wan");
584
		$interfacegwv6 = "wan";
585
		$gatewayipv6 = get_interface_gateway_v6("wan");
586
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
587
	}
588
	$dont_add_route = false;
589
	/* if OLSRD is enabled, allow WAN to house DHCP. */
590
	if (is_array($config['installedpackages']['olsrd'])) {
591
		foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
592
			if (($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
593
				$dont_add_route = true;
594
				log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
595
				break;
596
			}
597
		}
598
	}
599

    
600
	if ($dont_add_route == false) {
601
		if (!empty($interface) && $interface != $interfacegw) {
602
			;
603
		} else if (is_ipaddrv4($gatewayip)) {
604
			log_error("ROUTING: setting default route to $gatewayip");
605
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
606
		}
607

    
608
		if (!empty($interface) && $interface != $interfacegwv6) {
609
			;
610
		} else if (is_ipaddrv6($gatewayipv6)) {
611
			$ifscope = "";
612
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
613
				$ifscope = "%{$defaultifv6}";
614
			}
615
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
616
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
617
		}
618
	}
619

    
620
	system_staticroutes_configure($interface, false);
621

    
622
	return 0;
623
}
624

    
625
function system_staticroutes_configure($interface = "", $update_dns = false) {
626
	global $config, $g, $aliastable;
627

    
628
	$filterdns_list = array();
629

    
630
	$static_routes = get_staticroutes(false, true);
631
	if (count($static_routes)) {
632
		$gateways_arr = return_gateways_array(false, true);
633

    
634
		foreach ($static_routes as $rtent) {
635
			if (empty($gateways_arr[$rtent['gateway']])) {
636
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
637
				continue;
638
			}
639
			$gateway = $gateways_arr[$rtent['gateway']];
640
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
641
				continue;
642
			}
643

    
644
			$gatewayip = $gateway['gateway'];
645
			$interfacegw = $gateway['interface'];
646

    
647
			$blackhole = "";
648
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
649
				$blackhole = "-blackhole";
650
			}
651

    
652
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
653
				continue;
654
			}
655

    
656
			$dnscache = array();
657
			if ($update_dns === true) {
658
				if (is_subnet($rtent['network'])) {
659
					continue;
660
				}
661
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
662
				if (empty($dnscache)) {
663
					continue;
664
				}
665
			}
666

    
667
			if (is_subnet($rtent['network'])) {
668
				$ips = array($rtent['network']);
669
			} else {
670
				if (!isset($rtent['disabled'])) {
671
					$filterdns_list[] = $rtent['network'];
672
				}
673
				$ips = add_hostname_to_watch($rtent['network']);
674
			}
675

    
676
			foreach ($dnscache as $ip) {
677
				if (in_array($ip, $ips)) {
678
					continue;
679
				}
680
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
681
				if (isset($config['system']['route-debug'])) {
682
					$mt = microtime();
683
					log_error("ROUTING debug: $mt - route delete $ip ");
684
				}
685
			}
686

    
687
			if (isset($rtent['disabled'])) {
688
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
689
				foreach ($ips as $ip) {
690
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
691
					if (isset($config['system']['route-debug'])) {
692
						$mt = microtime();
693
						log_error("ROUTING debug: $mt - route delete $ip ");
694
					}
695
				}
696
				continue;
697
			}
698

    
699
			foreach ($ips as $ip) {
700
				if (is_ipaddrv4($ip)) {
701
					$ip .= "/32";
702
				}
703
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
704

    
705
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
706

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

    
709
				if (is_subnet($ip)) {
710
					if (is_ipaddr($gatewayip)) {
711
						mwexec($cmd . escapeshellarg($gatewayip));
712
						if (isset($config['system']['route-debug'])) {
713
							$mt = microtime();
714
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
715
						}
716
					} else if (!empty($interfacegw)) {
717
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
718
						if (isset($config['system']['route-debug'])) {
719
							$mt = microtime();
720
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
721
						}
722
					}
723
				}
724
			}
725
		}
726
		unset($gateways_arr);
727
	}
728
	unset($static_routes);
729

    
730
	if ($update_dns === false) {
731
		if (count($filterdns_list)) {
732
			$interval = 60;
733
			$hostnames = "";
734
			array_unique($filterdns_list);
735
			foreach ($filterdns_list as $hostname) {
736
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
737
			}
738
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
739
			unset($hostnames);
740

    
741
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
742
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
743
			} else {
744
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
745
			}
746
		} else {
747
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
748
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
749
		}
750
	}
751
	unset($filterdns_list);
752

    
753
	return 0;
754
}
755

    
756
function system_routing_enable() {
757
	global $config, $g;
758
	if (isset($config['system']['developerspew'])) {
759
		$mt = microtime();
760
		echo "system_routing_enable() being called $mt\n";
761
	}
762

    
763
	set_sysctl(array(
764
		"net.inet.ip.forwarding" => "1",
765
		"net.inet6.ip6.forwarding" => "1"
766
	));
767

    
768
	return;
769
}
770

    
771
function system_syslogd_fixup_server($server) {
772
	/* If it's an IPv6 IP alone, encase it in brackets */
773
	if (is_ipaddrv6($server)) {
774
		return "[$server]";
775
	} else {
776
		return $server;
777
	}
778
}
779

    
780
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
781
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
782
	$facility .= " ".
783
	$remote_servers = "";
784
	$pad_to  = 56;
785
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
786
	if ($syslogcfg['remoteserver']) {
787
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
788
	}
789
	if ($syslogcfg['remoteserver2']) {
790
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
791
	}
792
	if ($syslogcfg['remoteserver3']) {
793
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
794
	}
795
	return $remote_servers;
796
}
797

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

    
805
	mwexec("/etc/rc.d/hostid start");
806

    
807
	$syslogcfg = $config['syslog'];
808

    
809
	if (platform_booting()) {
810
		echo gettext("Starting syslog...");
811
	}
812

    
813
	if (is_process_running("fifolog_writer")) {
814
		mwexec('/bin/pkill fifolog_writer');
815
	}
816

    
817
	// Which logging type are we using this week??
818
	if (isset($config['system']['disablesyslogclog'])) {
819
		$log_directive = "";
820
		$log_create_directive = "/usr/bin/touch ";
821
		$log_size = "";
822
	} else if (isset($config['system']['usefifolog'])) {
823
		$log_directive = "|/usr/sbin/fifolog_writer ";
824
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
825
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
826
	} else { // Defaults to CLOG
827
		$log_directive = "%";
828
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
829
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
830
	}
831

    
832
	$syslogd_extra = "";
833
	if (isset($syslogcfg)) {
834
		$separatelogfacilities = array('ntp','ntpd','ntpdate','charon','ipsec_starter','openvpn','pptps','poes','l2tps','relayd','hostapd','dnsmasq','filterdns','unbound','dhcpd','dhcrelay','dhclient','dhcp6c','apinger','radvd','routed','olsrd','zebra','ospfd','bgpd','miniupnpd','filterlog');
835
		$syslogconf = "";
836
		if ($config['installedpackages']['package']) {
837
			foreach ($config['installedpackages']['package'] as $package) {
838
				if ($package['logging']) {
839
					array_push($separatelogfacilities, $package['logging']['facilityname']);
840
					mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
841
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
842
				}
843
			}
844
		}
845
		$facilitylist = implode(',', array_unique($separatelogfacilities));
846
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
847
		if (!isset($syslogcfg['disablelocallogging'])) {
848
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
849
		}
850

    
851
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
852
		if (!isset($syslogcfg['disablelocallogging'])) {
853
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
854
		}
855

    
856
		$syslogconf .= "!ppp\n";
857
		if (!isset($syslogcfg['disablelocallogging'])) {
858
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
859
		}
860

    
861
		$syslogconf .= "!pptps\n";
862
		if (!isset($syslogcfg['disablelocallogging'])) {
863
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
864
		}
865

    
866
		$syslogconf .= "!poes\n";
867
		if (!isset($syslogcfg['disablelocallogging'])) {
868
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
869
		}
870

    
871
		$syslogconf .= "!l2tps\n";
872
		if (!isset($syslogcfg['disablelocallogging'])) {
873
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
874
		}
875

    
876
		$syslogconf .= "!charon,ipsec_starter\n";
877
		if (!isset($syslogcfg['disablelocallogging'])) {
878
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
879
		}
880
		if (isset($syslogcfg['vpn'])) {
881
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
882
		}
883

    
884
		$syslogconf .= "!openvpn\n";
885
		if (!isset($syslogcfg['disablelocallogging'])) {
886
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
887
		}
888
		if (isset($syslogcfg['vpn'])) {
889
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
890
		}
891

    
892
		$syslogconf .= "!apinger\n";
893
		if (!isset($syslogcfg['disablelocallogging'])) {
894
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
895
		}
896
		if (isset($syslogcfg['apinger'])) {
897
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
898
		}
899

    
900
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
901
		if (!isset($syslogcfg['disablelocallogging'])) {
902
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
903
		}
904

    
905
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
906
		if (!isset($syslogcfg['disablelocallogging'])) {
907
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
908
		}
909
		if (isset($syslogcfg['dhcp'])) {
910
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
911
		}
912

    
913
		$syslogconf .= "!relayd\n";
914
		if (!isset($syslogcfg['disablelocallogging'])) {
915
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
916
		}
917
		if (isset($syslogcfg['relayd'])) {
918
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
919
		}
920

    
921
		$syslogconf .= "!hostapd\n";
922
		if (!isset($syslogcfg['disablelocallogging'])) {
923
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
924
		}
925
		if (isset($syslogcfg['hostapd'])) {
926
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
927
		}
928

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

    
935
		$syslogconf .= "!-{$facilitylist}\n";
936
		if (!isset($syslogcfg['disablelocallogging'])) {
937
			$syslogconf .= <<<EOD
938
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
939
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
940
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
941
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
942
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
943
local7.none							{$log_directive}{$g['varlog_path']}/system.log
944
security.*							{$log_directive}{$g['varlog_path']}/system.log
945
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
946
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
947
*.emerg								*
948

    
949
EOD;
950
		}
951
		if (isset($syslogcfg['vpn'])) {
952
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
953
		}
954
		if (isset($syslogcfg['portalauth'])) {
955
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
956
		}
957
		if (isset($syslogcfg['dhcp'])) {
958
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
959
		}
960
		if (isset($syslogcfg['system'])) {
961
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
962
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
963
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
964
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
965
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
966
		}
967
		if (isset($syslogcfg['logall'])) {
968
			// Make everything mean everything, including facilities excluded above.
969
			$syslogconf .= "!*\n";
970
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
971
		}
972

    
973
		if (isset($syslogcfg['zmqserver'])) {
974
				$syslogconf .= <<<EOD
975
*.*								^{$syslogcfg['zmqserver']}
976

    
977
EOD;
978
		}
979
		/* write syslog.conf */
980
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
981
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
982
			unset($syslogconf);
983
			return 1;
984
		}
985
		unset($syslogconf);
986

    
987
		// Ensure that the log directory exists
988
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
989
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
990
		}
991

    
992
		$sourceip = "";
993
		if (!empty($syslogcfg['sourceip'])) {
994
			if ($syslogcfg['ipproto'] == "ipv6") {
995
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
996
				if (!is_ipaddr($ifaddr)) {
997
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
998
				}
999
			} else {
1000
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1001
				if (!is_ipaddr($ifaddr)) {
1002
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1003
				}
1004
			}
1005
			if (is_ipaddr($ifaddr)) {
1006
				$sourceip = "-b {$ifaddr}";
1007
			}
1008
		}
1009

    
1010
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1011
	}
1012

    
1013
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1014
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1015
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1016
	}
1017

    
1018
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1019
		// if it still hasn't responded to the TERM, KILL it.
1020
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1021
		usleep(100000);
1022
	}
1023

    
1024

    
1025
	$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}");
1026

    
1027
	if (platform_booting()) {
1028
		echo gettext("done.") . "\n";
1029
	}
1030

    
1031
	return $retval;
1032
}
1033

    
1034
function system_webgui_create_certificate() {
1035
	global $config, $g;
1036

    
1037
	if (!is_array($config['ca'])) {
1038
		$config['ca'] = array();
1039
	}
1040
	$a_ca =& $config['ca'];
1041
	if (!is_array($config['cert'])) {
1042
		$config['cert'] = array();
1043
	}
1044
	$a_cert =& $config['cert'];
1045
	log_error("Creating SSL Certificate for this host");
1046

    
1047
	$cert = array();
1048
	$cert['refid'] = uniqid();
1049
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1050

    
1051
	$dn = array(
1052
		'countryName' => "US",
1053
		'stateOrProvinceName' => "State",
1054
		'localityName' => "Locality",
1055
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
1056
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
1057
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
1058
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
1059
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
1060
		while ($ssl_err = openssl_error_string()) {
1061
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
1062
		}
1063
		error_reporting($old_err_level);
1064
		return null;
1065
	}
1066
	error_reporting($old_err_level);
1067

    
1068
	$a_cert[] = $cert;
1069
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1070
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
1071
	return $cert;
1072
}
1073

    
1074
function system_webgui_start() {
1075
	global $config, $g;
1076

    
1077
	if (platform_booting()) {
1078
		echo gettext("Starting webConfigurator...");
1079
	}
1080

    
1081
	chdir($g['www_path']);
1082

    
1083
	/* defaults */
1084
	$portarg = "80";
1085
	$crt = "";
1086
	$key = "";
1087
	$ca = "";
1088

    
1089
	/* non-standard port? */
1090
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1091
		$portarg = "{$config['system']['webgui']['port']}";
1092
	}
1093

    
1094
	if ($config['system']['webgui']['protocol'] == "https") {
1095
		// Ensure that we have a webConfigurator CERT
1096
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1097
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1098
			$cert = system_webgui_create_certificate();
1099
		}
1100
		$crt = base64_decode($cert['crt']);
1101
		$key = base64_decode($cert['prv']);
1102

    
1103
		if (!$config['system']['webgui']['port']) {
1104
			$portarg = "443";
1105
		}
1106
		$ca  = ca_chain($cert);
1107
	}
1108

    
1109
	/* generate lighttpd configuration */
1110
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
1111
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
1112
		"cert.pem", "ca.pem");
1113

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

    
1117
	sleep(1);
1118

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

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

    
1124
	if (platform_booting()) {
1125
		if ($res == 0) {
1126
			echo gettext("done.") . "\n";
1127
		} else {
1128
			echo gettext("failed!") . "\n";
1129
		}
1130
	}
1131

    
1132
	return $res;
1133
}
1134

    
1135
function system_generate_lighty_config($filename,
1136
	$cert,
1137
	$key,
1138
	$ca,
1139
	$pid_file,
1140
	$port = 80,
1141
	$document_root = "/usr/local/www/",
1142
	$cert_location = "cert.pem",
1143
	$ca_location = "ca.pem",
1144
	$captive_portal = false) {
1145

    
1146
	global $config, $g;
1147

    
1148
	if (!is_dir("{$g['tmp_path']}/lighttpdcompress")) {
1149
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1150
	}
1151

    
1152
	if (isset($config['system']['developerspew'])) {
1153
		$mt = microtime();
1154
		echo "system_generate_lighty_config() being called $mt\n";
1155
	}
1156

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

    
1161
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1162
		if (empty($maxprocperip)) {
1163
			$maxprocperip = 10;
1164
		}
1165
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
1166

    
1167
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
1168
		if (!is_dir("{$g['tmp_path']}/captiveportal")) {
1169
			@mkdir("{$g['tmp_path']}/captiveportal", 0555);
1170
		}
1171
		$server_max_request_size = "server.max-request-size    = 384";
1172
		$cgi_config = "";
1173
	} else {
1174
		$captiveportal = ",\"mod_cgi\"";
1175
		$captive_portal_rewrite = "";
1176
		$captive_portal_mod_evasive = "";
1177
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
1178
		$server_max_request_size = "server.max-request-size    = 2097152";
1179
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
1180
	}
1181

    
1182
	if (empty($port)) {
1183
		$lighty_port = "80";
1184
	} else {
1185
		$lighty_port = $port;
1186
	}
1187

    
1188
	$memory = get_memory();
1189
	$realmem = $memory[1];
1190

    
1191
	// Determine web GUI process settings and take into account low memory systems
1192
	if ($realmem < 255) {
1193
		$max_procs = 1;
1194
	} else {
1195
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1196
	}
1197

    
1198
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
1199
	if ($captive_portal !== false)  {
1200
		if ($realmem > 135 and $realmem < 256) {
1201
			$max_procs += 1; // 2 worker processes
1202
		} else if ($realmem > 255 and $realmem < 513) {
1203
			$max_procs += 2; // 3 worker processes
1204
		} else if ($realmem > 512) {
1205
			$max_procs += 4; // 6 worker processes
1206
		}
1207
		if ($max_procs > 1) {
1208
			$max_php_children = intval($max_procs/2);
1209
		} else {
1210
			$max_php_children = 1;
1211
		}
1212

    
1213
	} else {
1214
		if ($realmem < 78) {
1215
			$max_php_children = 0;
1216
		} else {
1217
			$max_php_children = 1;
1218
		}
1219
	}
1220

    
1221
	if (!isset($config['syslog']['nologlighttpd'])) {
1222
		$lighty_use_syslog = <<<EOD
1223
## where to send error-messages to
1224
server.errorlog-use-syslog="enable"
1225
EOD;
1226
	}
1227

    
1228

    
1229
	if ($captive_portal !== false) {
1230
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
1231
		$fastcgi_config = <<<EOD
1232
#### fastcgi module
1233
## read fastcgi.txt for more info
1234
fastcgi.server = ( ".php" =>
1235
	( "localhost" =>
1236
		(
1237
			"socket" => "{$fast_cgi_path}",
1238
			"max-procs" => {$max_procs},
1239
			"bin-environment" => (
1240
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
1241
				"PHP_FCGI_MAX_REQUESTS" => "500"
1242
			),
1243
			"bin-path" => "/usr/local/bin/php"
1244
		)
1245
	)
1246
)
1247

    
1248
EOD;
1249
	} else {
1250
		$fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
1251
		$fastcgi_config = <<<EOD
1252
#### fastcgi module
1253
## read fastcgi.txt for more info
1254
fastcgi.server = ( ".php" =>
1255
	( "localhost" =>
1256
		(
1257
			"socket" => "{$fast_cgi_path}",
1258
			"broken-scriptfilename" => "enable"
1259
		)
1260
	)
1261
)
1262

    
1263
EOD;
1264
	}
1265

    
1266

    
1267
	$lighty_config = <<<EOD
1268
#
1269
# lighttpd configuration file
1270
#
1271
# use a it as base for lighttpd 1.0.0 and above
1272
#
1273
############ Options you really have to take care of ####################
1274

    
1275
## FreeBSD!
1276
server.event-handler	= "freebsd-kqueue"
1277
server.network-backend 	= "writev"
1278
#server.use-ipv6 = "enable"
1279

    
1280
## modules to load
1281
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1282
	{$captiveportal}, "mod_fastcgi"
1283
)
1284

    
1285
server.max-keep-alive-requests = 15
1286
server.max-keep-alive-idle = 30
1287

    
1288
## a static document-root, for virtual-hosting take look at the
1289
## server.virtual-* options
1290
server.document-root        = "{$document_root}"
1291
{$captive_portal_rewrite}
1292

    
1293
# Maximum idle time with nothing being written (php downloading)
1294
server.max-write-idle = 999
1295

    
1296
{$lighty_use_syslog}
1297

    
1298
# files to check for if .../ is requested
1299
server.indexfiles           = ( "index.php", "index.html",
1300
                                "index.htm", "default.htm" )
1301

    
1302
# mimetype mapping
1303
mimetype.assign             = (
1304
  ".pdf"          =>      "application/pdf",
1305
  ".sig"          =>      "application/pgp-signature",
1306
  ".spl"          =>      "application/futuresplash",
1307
  ".class"        =>      "application/octet-stream",
1308
  ".ps"           =>      "application/postscript",
1309
  ".torrent"      =>      "application/x-bittorrent",
1310
  ".dvi"          =>      "application/x-dvi",
1311
  ".gz"           =>      "application/x-gzip",
1312
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
1313
  ".swf"          =>      "application/x-shockwave-flash",
1314
  ".tar.gz"       =>      "application/x-tgz",
1315
  ".tgz"          =>      "application/x-tgz",
1316
  ".tar"          =>      "application/x-tar",
1317
  ".zip"          =>      "application/zip",
1318
  ".mp3"          =>      "audio/mpeg",
1319
  ".m3u"          =>      "audio/x-mpegurl",
1320
  ".wma"          =>      "audio/x-ms-wma",
1321
  ".wax"          =>      "audio/x-ms-wax",
1322
  ".ogg"          =>      "audio/x-wav",
1323
  ".wav"          =>      "audio/x-wav",
1324
  ".gif"          =>      "image/gif",
1325
  ".jpg"          =>      "image/jpeg",
1326
  ".jpeg"         =>      "image/jpeg",
1327
  ".png"          =>      "image/png",
1328
  ".xbm"          =>      "image/x-xbitmap",
1329
  ".xpm"          =>      "image/x-xpixmap",
1330
  ".xwd"          =>      "image/x-xwindowdump",
1331
  ".css"          =>      "text/css",
1332
  ".html"         =>      "text/html",
1333
  ".htm"          =>      "text/html",
1334
  ".js"           =>      "text/javascript",
1335
  ".asc"          =>      "text/plain",
1336
  ".c"            =>      "text/plain",
1337
  ".conf"         =>      "text/plain",
1338
  ".text"         =>      "text/plain",
1339
  ".txt"          =>      "text/plain",
1340
  ".dtd"          =>      "text/xml",
1341
  ".xml"          =>      "text/xml",
1342
  ".mpeg"         =>      "video/mpeg",
1343
  ".mpg"          =>      "video/mpeg",
1344
  ".mov"          =>      "video/quicktime",
1345
  ".qt"           =>      "video/quicktime",
1346
  ".avi"          =>      "video/x-msvideo",
1347
  ".asf"          =>      "video/x-ms-asf",
1348
  ".asx"          =>      "video/x-ms-asf",
1349
  ".wmv"          =>      "video/x-ms-wmv",
1350
  ".bz2"          =>      "application/x-bzip",
1351
  ".tbz"          =>      "application/x-bzip-compressed-tar",
1352
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
1353
 )
1354

    
1355
# Use the "Content-Type" extended attribute to obtain mime type if possible
1356
#mimetypes.use-xattr        = "enable"
1357

    
1358
## deny access the file-extensions
1359
#
1360
# ~    is for backupfiles from vi, emacs, joe, ...
1361
# .inc is often used for code includes which should in general not be part
1362
#      of the document-root
1363
url.access-deny             = ( "~", ".inc" )
1364

    
1365

    
1366
######### Options that are good to be but not necessary to be changed #######
1367

    
1368
## bind to port (default: 80)
1369

    
1370
EOD;
1371

    
1372
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1373
	$lighty_config .= "server.port  = {$lighty_port}\n";
1374
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1375
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1376
	if ($cert <> "" and $key <> "") {
1377
		$lighty_config .= "\n";
1378
		$lighty_config .= "## ssl configuration\n";
1379
		$lighty_config .= "ssl.engine = \"enable\"\n";
1380
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1381
		if ($ca <> "") {
1382
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1383
		}
1384
	}
1385
	$lighty_config .= " }\n";
1386

    
1387

    
1388
	$lighty_config .= <<<EOD
1389

    
1390
## error-handler for status 404
1391
#server.error-handler-404   = "/error-handler.html"
1392
#server.error-handler-404   = "/error-handler.php"
1393

    
1394
## to help the rc.scripts
1395
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1396

    
1397
## virtual directory listings
1398
server.dir-listing         = "disable"
1399

    
1400
## enable debugging
1401
debug.log-request-header   = "disable"
1402
debug.log-response-header  = "disable"
1403
debug.log-request-handling = "disable"
1404
debug.log-file-not-found   = "disable"
1405

    
1406
# gzip compression
1407
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1408
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1409

    
1410
{$server_upload_dirs}
1411

    
1412
{$server_max_request_size}
1413

    
1414
{$fastcgi_config}
1415

    
1416
{$cgi_config}
1417

    
1418
{$captive_portal_mod_evasive}
1419

    
1420
expire.url = (
1421
		"" => "access 50 hours",
1422
	)
1423

    
1424
EOD;
1425

    
1426
	$cert = str_replace("\r", "", $cert);
1427
	$key = str_replace("\r", "", $key);
1428
	$ca = str_replace("\r", "", $ca);
1429

    
1430
	$cert = str_replace("\n\n", "\n", $cert);
1431
	$key = str_replace("\n\n", "\n", $key);
1432
	$ca = str_replace("\n\n", "\n", $ca);
1433

    
1434
	if ($cert <> "" and $key <> "") {
1435
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1436
		if (!$fd) {
1437
			printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
1438
			return 1;
1439
		}
1440
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1441
		fwrite($fd, $cert);
1442
		fwrite($fd, "\n");
1443
		fwrite($fd, $key);
1444
		fclose($fd);
1445
		if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
1446
			$fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
1447
			if (!$fd) {
1448
				printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
1449
				return 1;
1450
			}
1451
			chmod("{$g['varetc_path']}/{$ca_location}", 0600);
1452
			fwrite($fd, $ca);
1453
			fclose($fd);
1454
		}
1455
		$lighty_config .= "\n";
1456
		$lighty_config .= "## " . gettext("ssl configuration") . "\n";
1457
		$lighty_config .= "ssl.engine = \"enable\"\n";
1458
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1459

    
1460
		// SSLv2/3 is deprecated, force use of TLS
1461
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1462
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1463

    
1464
		/* Hifn accelerators do NOT work with the BEAST mitigation code. Do not allow it to be enabled if a Hifn card has been detected. */
1465
		$fd = @fopen("{$g['varlog_path']}/dmesg.boot", "r");
1466
		if ($fd) {
1467
			while (!feof($fd)) {
1468
				$dmesgl = fgets($fd);
1469
				if (preg_match("/^hifn.: (.*?),/", $dmesgl, $matches) && isset($config['system']['webgui']['beast_protection'])) {
1470
					unset($config['system']['webgui']['beast_protection']);
1471
					log_error("BEAST Protection disabled because a conflicting cryptographic accelerator card has been detected (" . $matches[1] . ")");
1472
					break;
1473
				}
1474
			}
1475
			fclose($fd);
1476
		}
1477

    
1478
		if (isset($config['system']['webgui']['beast_protection'])) {
1479
			$lighty_config .= "ssl.honor-cipher-order = \"enable\"\n";
1480
			$lighty_config .= "ssl.cipher-list = \"ECDHE-RSA-AES256-SHA384:AES256-SHA256:HIGH:!MD5:!aNULL:!EDH:!AESGCM\"\n";
1481
		} else {
1482
			$lighty_config .= "ssl.cipher-list = \"DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:CAMELLIA256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:CAMELLIA128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:!aNULL:!eNULL:!3DES:@STRENGTH\"\n";
1483
		}
1484

    
1485
		if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
1486
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1487
		}
1488
	}
1489

    
1490
	// Add HTTP to HTTPS redirect
1491
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1492
		if ($lighty_port != "443") {
1493
			$redirectport = ":{$lighty_port}";
1494
		}
1495
		$lighty_config .= <<<EOD
1496
\$SERVER["socket"] == ":80" {
1497
	\$HTTP["host"] =~ "(.*)" {
1498
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1499
	}
1500
}
1501
\$SERVER["socket"] == "[::]:80" {
1502
	\$HTTP["host"] =~ "(.*)" {
1503
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1504
	}
1505
}
1506
EOD;
1507
	}
1508

    
1509
	$fd = fopen("{$filename}", "w");
1510
	if (!$fd) {
1511
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1512
		return 1;
1513
	}
1514
	fwrite($fd, $lighty_config);
1515
	fclose($fd);
1516

    
1517
	return 0;
1518

    
1519
}
1520

    
1521
function system_timezone_configure() {
1522
	global $config, $g;
1523
	if (isset($config['system']['developerspew'])) {
1524
		$mt = microtime();
1525
		echo "system_timezone_configure() being called $mt\n";
1526
	}
1527

    
1528
	$syscfg = $config['system'];
1529

    
1530
	if (platform_booting()) {
1531
		echo gettext("Setting timezone...");
1532
	}
1533

    
1534
	/* extract appropriate timezone file */
1535
	$timezone = $syscfg['timezone'];
1536
	if ($timezone) {
1537
		exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
1538
		foreach ($tzs as $tz) {
1539
			if (preg_match(",{$timezone}$,", $tz)) {
1540
				break;
1541
			}
1542
			if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
1543
				$timezone = $matches[1];
1544
				break;
1545
			}
1546
		}
1547
	} else {
1548
		$timezone = "Etc/UTC";
1549
	}
1550

    
1551
	conf_mount_rw();
1552

    
1553
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1554
		escapeshellarg($timezone) . " > /etc/localtime");
1555

    
1556
	mwexec("sync");
1557
	conf_mount_ro();
1558

    
1559
	if (platform_booting()) {
1560
		echo gettext("done.") . "\n";
1561
	}
1562
}
1563

    
1564
function system_ntp_setup_gps($serialport) {
1565
	global $config, $g;
1566
	$gps_device = '/dev/gps0';
1567
	$serialport = '/dev/'.$serialport;
1568

    
1569
	if (!file_exists($serialport)) {
1570
		return false;
1571
	}
1572

    
1573
	conf_mount_rw();
1574
	// Create symlink that ntpd requires
1575
	unlink_if_exists($gps_device);
1576
	@symlink($serialport, $gps_device);
1577

    
1578
	$gpsbaud = '4800';
1579
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1580
		switch ($config['ntpd']['gps']['speed']) {
1581
			case '16':
1582
				$gpsbaud = '9600';
1583
				break;
1584
			case '32':
1585
				$gpsbaud = '19200';
1586
				break;
1587
			case '48':
1588
				$gpsbaud = '38400';
1589
				break;
1590
			case '64':
1591
				$gpsbaud = '57600';
1592
				break;
1593
			case '80':
1594
				$gpsbaud = '115200';
1595
				break;
1596
		}
1597
	}
1598

    
1599
	/* Configure the serial port for raw IO and set the speed */
1600
	`stty -f {$serialport}.init raw speed {$gpsbaud}`
1601

    
1602
	/* Send the following to the GPS port to initialize the GPS */
1603
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1604
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1605
	} else {
1606
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1607
	}
1608

    
1609
	/* XXX: Why not file_put_contents to the device */
1610
	@file_put_contents('/tmp/gps.init', $gps_init);
1611
	`cat /tmp/gps.init > $serialport`;
1612

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

    
1618
	conf_mount_ro();
1619

    
1620
	return true;
1621
}
1622

    
1623
function system_ntp_setup_pps($serialport) {
1624
	global $config, $g;
1625

    
1626
	$pps_device = '/dev/pps0';
1627
	$serialport = '/dev/'.$serialport;
1628

    
1629
	if (!file_exists($serialport)) {
1630
		return false;
1631
	}
1632

    
1633
	conf_mount_rw();
1634
	// Create symlink that ntpd requires
1635
	unlink_if_exists($pps_device);
1636
	@symlink($serialport, $pps_device);
1637

    
1638
	conf_mount_ro();
1639

    
1640
	return true;
1641
}
1642

    
1643

    
1644
function system_ntp_configure($start_ntpd=true) {
1645
	global $config, $g;
1646

    
1647
	$driftfile = "/var/db/ntpd.drift";
1648
	$statsdir = "/var/log/ntp";
1649
	$gps_device = '/dev/gps0';
1650

    
1651
	if ($g['platform'] == 'jail') {
1652
		return;
1653
	}
1654

    
1655
	safe_mkdir($statsdir);
1656

    
1657
	if (!is_array($config['ntpd'])) {
1658
		$config['ntpd'] = array();
1659
	}
1660

    
1661
	$ntpcfg = "# \n";
1662
	$ntpcfg .= "# pfSense ntp configuration file \n";
1663
	$ntpcfg .= "# \n\n";
1664
	$ntpcfg .= "tinker panic 0 \n";
1665

    
1666
	/* Add Orphan mode */
1667
	$ntpcfg .= "# Orphan mode stratum\n";
1668
	$ntpcfg .= 'tos orphan ';
1669
	if (!empty($config['ntpd']['orphan'])) {
1670
		$ntpcfg .= $config['ntpd']['orphan'];
1671
	} else {
1672
		$ntpcfg .= '12';
1673
	}
1674
	$ntpcfg .= "\n";
1675

    
1676
	/* Add PPS configuration */
1677
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
1678
	    file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
1679
	    system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1680
		$ntpcfg .= "\n";
1681
		$ntpcfg .= "# PPS Setup\n";
1682
		$ntpcfg .= 'server 127.127.22.0';
1683
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1684
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1685
			$ntpcfg .= ' prefer';
1686
		}
1687
		if (!empty($config['ntpd']['pps']['noselect'])) {
1688
			$ntpcfg .= ' noselect ';
1689
		}
1690
		$ntpcfg .= "\n";
1691
		$ntpcfg .= 'fudge 127.127.22.0';
1692
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1693
			$ntpcfg .= ' time1 ';
1694
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1695
		}
1696
		if (!empty($config['ntpd']['pps']['flag2'])) {
1697
			$ntpcfg .= ' flag2 1';
1698
		}
1699
		if (!empty($config['ntpd']['pps']['flag3'])) {
1700
			$ntpcfg .= ' flag3 1';
1701
		} else {
1702
			$ntpcfg .= ' flag3 0';
1703
		}
1704
		if (!empty($config['ntpd']['pps']['flag4'])) {
1705
			$ntpcfg .= ' flag4 1';
1706
		}
1707
		if (!empty($config['ntpd']['pps']['refid'])) {
1708
			$ntpcfg .= ' refid ';
1709
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1710
		}
1711
		$ntpcfg .= "\n";
1712
	}
1713
	/* End PPS configuration */
1714

    
1715
	/* Add GPS configuration */
1716
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
1717
	    file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
1718
	    system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1719
		$ntpcfg .= "\n";
1720
		$ntpcfg .= "# GPS Setup\n";
1721
		$ntpcfg .= 'server 127.127.20.0 mode ';
1722
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1723
			if (!empty($config['ntpd']['gps']['nmea'])) {
1724
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1725
			}
1726
			if (!empty($config['ntpd']['gps']['speed'])) {
1727
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1728
			}
1729
			if (!empty($config['ntpd']['gps']['subsec'])) {
1730
				$ntpmode += 128;
1731
			}
1732
			$ntpcfg .= (string) $ntpmode;
1733
		} else {
1734
			$ntpcfg .= '0';
1735
		}
1736
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1737
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1738
			$ntpcfg .= ' prefer';
1739
		}
1740
		if (!empty($config['ntpd']['gps']['noselect'])) {
1741
			$ntpcfg .= ' noselect ';
1742
		}
1743
		$ntpcfg .= "\n";
1744
		$ntpcfg .= 'fudge 127.127.20.0';
1745
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1746
			$ntpcfg .= ' time1 ';
1747
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1748
		}
1749
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1750
			$ntpcfg .= ' time2 ';
1751
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1752
		}
1753
		if (!empty($config['ntpd']['gps']['flag1'])) {
1754
			$ntpcfg .= ' flag1 1';
1755
		} else {
1756
			$ntpcfg .= ' flag1 0';
1757
		}
1758
		if (!empty($config['ntpd']['gps']['flag2'])) {
1759
			$ntpcfg .= ' flag2 1';
1760
		}
1761
		if (!empty($config['ntpd']['gps']['flag3'])) {
1762
			$ntpcfg .= ' flag3 1';
1763
		} else {
1764
			$ntpcfg .= ' flag3 0';
1765
		}
1766
		if (!empty($config['ntpd']['gps']['flag4'])) {
1767
			$ntpcfg .= ' flag4 1';
1768
		}
1769
		if (!empty($config['ntpd']['gps']['refid'])) {
1770
			$ntpcfg .= ' refid ';
1771
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1772
		}
1773
		$ntpcfg .= "\n";
1774
	} elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
1775
	    file_exists('/dev/'.$config['ntpd']['gpsport']) &&
1776
	    system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1777
		/* This handles a 2.1 and earlier config */
1778
		$ntpcfg .= "# GPS Setup\n";
1779
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1780
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1781
		// Fall back to local clock if GPS is out of sync?
1782
		$ntpcfg .= "server 127.127.1.0\n";
1783
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1784
	}
1785
	/* End GPS configuration */
1786

    
1787
	$ntpcfg .= "\n\n# Upstream Servers\n";
1788
	/* foreach through ntp servers and write out to ntpd.conf */
1789
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1790
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1791
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1792
			$ntpcfg .= ' prefer';
1793
		}
1794
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1795
			$ntpcfg .= ' noselect';
1796
		}
1797
		$ntpcfg .= "\n";
1798
	}
1799
	unset($ts);
1800

    
1801
	$ntpcfg .= "\n\n";
1802
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1803
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1804
		$ntpcfg .= "enable stats\n";
1805
		$ntpcfg .= 'statistics';
1806
		if (!empty($config['ntpd']['clockstats'])) {
1807
			$ntpcfg .= ' clockstats';
1808
		}
1809
		if (!empty($config['ntpd']['loopstats'])) {
1810
			$ntpcfg .= ' loopstats';
1811
		}
1812
		if (!empty($config['ntpd']['peerstats'])) {
1813
			$ntpcfg .= ' peerstats';
1814
		}
1815
		$ntpcfg .= "\n";
1816
	}
1817
	$ntpcfg .= "statsdir {$statsdir}\n";
1818
	$ntpcfg .= 'logconfig =syncall +clockall';
1819
	if (!empty($config['ntpd']['logpeer'])) {
1820
		$ntpcfg .= ' +peerall';
1821
	}
1822
	if (!empty($config['ntpd']['logsys'])) {
1823
		$ntpcfg .= ' +sysall';
1824
	}
1825
	$ntpcfg .= "\n";
1826
	$ntpcfg .= "driftfile {$driftfile}\n";
1827
	/* Access restrictions */
1828
	$ntpcfg .= 'restrict default';
1829
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1830
		$ntpcfg .= ' kod limited';
1831
	}
1832
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1833
		$ntpcfg .= ' nomodify';
1834
	}
1835
	if (!empty($config['ntpd']['noquery'])) {
1836
		$ntpcfg .= ' noquery';
1837
	}
1838
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1839
		$ntpcfg .= ' nopeer';
1840
	}
1841
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1842
		$ntpcfg .= ' notrap';
1843
	}
1844
	if (!empty($config['ntpd']['noserve'])) {
1845
		$ntpcfg .= ' noserve';
1846
	}
1847
	$ntpcfg .= "\nrestrict -6 default";
1848
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1849
		$ntpcfg .= ' kod limited';
1850
	}
1851
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1852
		$ntpcfg .= ' nomodify';
1853
	}
1854
	if (!empty($config['ntpd']['noquery'])) {
1855
		$ntpcfg .= ' noquery';
1856
	}
1857
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1858
		$ntpcfg .= ' nopeer';
1859
	}
1860
	if (!empty($config['ntpd']['noserve'])) {
1861
		$ntpcfg .= ' noserve';
1862
	}
1863
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1864
		$ntpcfg .= ' notrap';
1865
	}
1866
	$ntpcfg .= "\n";
1867

    
1868
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1869
	$ntpcfg .= "\n";
1870
	if (!empty($config['ntpd']['leapsec'])) {
1871
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1872
		file_put_contents('/var/db/leap-seconds', $leapsec);
1873
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1874
	}
1875

    
1876

    
1877
	if (empty($config['ntpd']['interface'])) {
1878
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1879
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1880
		} else {
1881
			$interfaces = array();
1882
		}
1883
	} else {
1884
		$interfaces = explode(",", $config['ntpd']['interface']);
1885
	}
1886

    
1887
	if (is_array($interfaces) && count($interfaces)) {
1888
		$ntpcfg .= "interface ignore all\n";
1889
		foreach ($interfaces as $interface) {
1890
			if (!is_ipaddr($interface)) {
1891
				$interface = get_real_interface($interface);
1892
			}
1893
			if (!empty($interface)) {
1894
				$ntpcfg .= "interface listen {$interface}\n";
1895
			}
1896
		}
1897
	}
1898

    
1899
	/* open configuration for writing or bail */
1900
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1901
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1902
		return;
1903
	}
1904

    
1905
	/* At bootup we just want to write out the config. */
1906
	if (!$start_ntpd) {
1907
		return;
1908
	}
1909

    
1910
	/* if ntpd is running, kill it */
1911
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1912
		killbypid("{$g['varrun_path']}/ntpd.pid");
1913
	}
1914
	@unlink("{$g['varrun_path']}/ntpd.pid");
1915

    
1916
	/* if /var/empty does not exist, create it */
1917
	if (!is_dir("/var/empty")) {
1918
		mkdir("/var/empty", 0775, true);
1919
	}
1920

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

    
1924
	// Note that we are starting up
1925
	log_error("NTPD is starting up.");
1926
	return;
1927
}
1928

    
1929
function sync_system_time() {
1930
	global $config, $g;
1931

    
1932
	if (platform_booting()) {
1933
		echo gettext("Syncing system time before startup...");
1934
	}
1935

    
1936
	/* foreach through servers and write out to ntpd.conf */
1937
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1938
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1939
	}
1940

    
1941
	if (platform_booting()) {
1942
		echo gettext("done.") . "\n";
1943
	}
1944

    
1945
}
1946

    
1947
function system_halt() {
1948
	global $g;
1949

    
1950
	system_reboot_cleanup();
1951

    
1952
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1953
}
1954

    
1955
function system_reboot() {
1956
	global $g;
1957

    
1958
	system_reboot_cleanup();
1959

    
1960
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1961
}
1962

    
1963
function system_reboot_sync() {
1964
	global $g;
1965

    
1966
	system_reboot_cleanup();
1967

    
1968
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1969
}
1970

    
1971
function system_reboot_cleanup() {
1972
	global $config, $cpzone;
1973

    
1974
	mwexec("/usr/local/bin/beep.sh stop");
1975
	require_once("captiveportal.inc");
1976
	if (is_array($config['captiveportal'])) {
1977
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1978
			captiveportal_radius_stop_all();
1979
			captiveportal_send_server_accounting(true);
1980
		}
1981
	}
1982
	require_once("voucher.inc");
1983
	voucher_save_db_to_config();
1984
	require_once("pkg-utils.inc");
1985
	stop_packages();
1986
}
1987

    
1988
function system_do_shell_commands($early = 0) {
1989
	global $config, $g;
1990
	if (isset($config['system']['developerspew'])) {
1991
		$mt = microtime();
1992
		echo "system_do_shell_commands() being called $mt\n";
1993
	}
1994

    
1995
	if ($early) {
1996
		$cmdn = "earlyshellcmd";
1997
	} else {
1998
		$cmdn = "shellcmd";
1999
	}
2000

    
2001
	if (is_array($config['system'][$cmdn])) {
2002

    
2003
		/* *cmd is an array, loop through */
2004
		foreach ($config['system'][$cmdn] as $cmd) {
2005
			exec($cmd);
2006
		}
2007

    
2008
	} elseif ($config['system'][$cmdn] <> "") {
2009

    
2010
		/* execute single item */
2011
		exec($config['system'][$cmdn]);
2012

    
2013
	}
2014
}
2015

    
2016
function system_console_configure() {
2017
	global $config, $g;
2018
	if (isset($config['system']['developerspew'])) {
2019
		$mt = microtime();
2020
		echo "system_console_configure() being called $mt\n";
2021
	}
2022

    
2023
	if (isset($config['system']['disableconsolemenu'])) {
2024
		touch("{$g['varetc_path']}/disableconsole");
2025
	} else {
2026
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
2027
	}
2028
}
2029

    
2030
function system_dmesg_save() {
2031
	global $g;
2032
	if (isset($config['system']['developerspew'])) {
2033
		$mt = microtime();
2034
		echo "system_dmesg_save() being called $mt\n";
2035
	}
2036

    
2037
	$dmesg = "";
2038
	$_gb = exec("/sbin/dmesg", $dmesg);
2039

    
2040
	/* find last copyright line (output from previous boots may be present) */
2041
	$lastcpline = 0;
2042

    
2043
	for ($i = 0; $i < count($dmesg); $i++) {
2044
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
2045
			$lastcpline = $i;
2046
		}
2047
	}
2048

    
2049
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
2050
	if (!$fd) {
2051
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
2052
		return 1;
2053
	}
2054

    
2055
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
2056
		fwrite($fd, $dmesg[$i] . "\n");
2057
	}
2058

    
2059
	fclose($fd);
2060
	unset($dmesg);
2061

    
2062
	return 0;
2063
}
2064

    
2065
function system_set_harddisk_standby() {
2066
	global $g, $config;
2067
	if (isset($config['system']['developerspew'])) {
2068
		$mt = microtime();
2069
		echo "system_set_harddisk_standby() being called $mt\n";
2070
	}
2071

    
2072
	if (isset($config['system']['harddiskstandby'])) {
2073
		if (platform_booting()) {
2074
			echo gettext('Setting hard disk standby... ');
2075
		}
2076

    
2077
		$standby = $config['system']['harddiskstandby'];
2078
		// Check for a numeric value
2079
		if (is_numeric($standby)) {
2080
			// Sync the disk(s)
2081
			pfSense_sync();
2082
			if (set_single_sysctl('hw.ata.standby', (int)$standby)) {
2083
				// Reinitialize ATA-drives
2084
				mwexec('/usr/local/sbin/atareinit');
2085
				if (platform_booting()) {
2086
					echo gettext("done.") . "\n";
2087
				}
2088
			} else if (platform_booting()) {
2089
				echo gettext("failed!") . "\n";
2090
			}
2091
		} else if (platform_booting()) {
2092
			echo gettext("failed!") . "\n";
2093
		}
2094
	}
2095
}
2096

    
2097
function system_setup_sysctl() {
2098
	global $config;
2099
	if (isset($config['system']['developerspew'])) {
2100
		$mt = microtime();
2101
		echo "system_setup_sysctl() being called $mt\n";
2102
	}
2103

    
2104
	activate_sysctls();
2105

    
2106
	if (isset($config['system']['sharednet'])) {
2107
		system_disable_arp_wrong_if();
2108
	}
2109
}
2110

    
2111
function system_disable_arp_wrong_if() {
2112
	global $config;
2113
	if (isset($config['system']['developerspew'])) {
2114
		$mt = microtime();
2115
		echo "system_disable_arp_wrong_if() being called $mt\n";
2116
	}
2117
	set_sysctl(array(
2118
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2119
		"net.link.ether.inet.log_arp_movements" => "0"
2120
	));
2121
}
2122

    
2123
function system_enable_arp_wrong_if() {
2124
	global $config;
2125
	if (isset($config['system']['developerspew'])) {
2126
		$mt = microtime();
2127
		echo "system_enable_arp_wrong_if() being called $mt\n";
2128
	}
2129
	set_sysctl(array(
2130
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2131
		"net.link.ether.inet.log_arp_movements" => "1"
2132
	));
2133
}
2134

    
2135
function enable_watchdog() {
2136
	global $config;
2137
	return;
2138
	$install_watchdog = false;
2139
	$supported_watchdogs = array("Geode");
2140
	$file = file_get_contents("/var/log/dmesg.boot");
2141
	foreach ($supported_watchdogs as $sd) {
2142
		if (stristr($file, "Geode")) {
2143
			$install_watchdog = true;
2144
		}
2145
	}
2146
	if ($install_watchdog == true) {
2147
		if (is_process_running("watchdogd")) {
2148
			mwexec("/usr/bin/killall watchdogd", true);
2149
		}
2150
		exec("/usr/sbin/watchdogd");
2151
	}
2152
}
2153

    
2154
function system_check_reset_button() {
2155
	global $g;
2156

    
2157
	$specplatform = system_identify_specific_platform();
2158

    
2159
	switch ($specplatform['name']) {
2160
		case 'alix':
2161
		case 'wrap':
2162
		case 'FW7541':
2163
		case 'APU':
2164
		case 'C2358':
2165
			break;
2166
		default:
2167
			return 0;
2168
	}
2169

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

    
2172
	if ($retval == 99) {
2173
		/* user has pressed reset button for 2 seconds -
2174
		   reset to factory defaults */
2175
		echo <<<EOD
2176

    
2177
***********************************************************************
2178
* Reset button pressed - resetting configuration to factory defaults. *
2179
* The system will reboot after this completes.                        *
2180
***********************************************************************
2181

    
2182

    
2183
EOD;
2184

    
2185
		reset_factory_defaults();
2186
		system_reboot_sync();
2187
		exit(0);
2188
	}
2189

    
2190
	return 0;
2191
}
2192

    
2193
/* attempt to identify the specific platform (for embedded systems)
2194
   Returns an array with two elements:
2195
	name => platform string (e.g. 'wrap', 'alix' etc.)
2196
	descr => human-readable description (e.g. "PC Engines WRAP")
2197
*/
2198
function system_identify_specific_platform() {
2199
	global $g;
2200

    
2201
	if ($g['platform'] == 'generic-pc') {
2202
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2203
	}
2204

    
2205
	if ($g['platform'] == 'generic-pc-cdrom') {
2206
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2207
	}
2208

    
2209
	/* Try to guess from smbios strings */
2210
	unset($output);
2211
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2212
	switch ($output[0]) {
2213
		case 'FW7541':
2214
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2215
			break;
2216
		case 'APU':
2217
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2218
			break;
2219
		case 'RCC-VE':
2220
			return (array('name' => 'C2358', 'descr' => 'Netgate C2358'));
2221
			break;
2222
	}
2223

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

    
2229
	$dmesg = get_single_sysctl('hw.model');
2230

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

    
2235
	if (strpos($dmesg, "PC Engines ALIX") !== false) {
2236
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2237
	}
2238

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

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

    
2247
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2248
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2249
	}
2250

    
2251
	unset($dmesg);
2252

    
2253
	$dmesg_boot = system_get_dmesg_boot();
2254
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2255
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2256
	}
2257
	unset($dmesg_boot);
2258

    
2259
	/* unknown embedded platform */
2260
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2261
}
2262

    
2263
function system_get_dmesg_boot() {
2264
	global $g;
2265

    
2266
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2267
}
2268

    
2269
?>
(53-53/68)