Project

General

Profile

Download (66.8 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
		$ns = array();
180
		// Do not create blank search/domain lines, it can break tools like dig.
181
		if ($syscfg['domain']) {
182
			$resolvconf .= "search {$syscfg['domain']}\n";
183
		}
184
	}
185
	if (is_array($syscfg['dnsserver'])) {
186
		foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
187
			if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
188
				$resolvconf .= "nameserver $sys_dnsserver\n";
189
			}
190
		}
191
	}
192

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

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

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

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

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

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

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

    
256
	unlock($dnslock);
257

    
258
	return 0;
259
}
260

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

    
264
	$master_list = array();
265

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

    
282
	return $master_list;
283
}
284

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

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

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

    
317
	return $master_list;
318
}
319

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

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

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

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

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

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

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

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

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

    
451
	return 0;
452
}
453

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

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

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

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

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

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

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

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

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

    
517
	return $status;
518
}
519

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

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

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

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

    
621
	system_staticroutes_configure($interface, false);
622

    
623
	return 0;
624
}
625

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

    
629
	$filterdns_list = array();
630

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
754
	return 0;
755
}
756

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

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

    
769
	return;
770
}
771

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

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

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

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

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

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

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

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

    
833
	$syslogd_extra = "";
834
	if (isset($syslogcfg)) {
835
		$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');
836
		$syslogconf = "";
837
		if ($config['installedpackages']['package']) {
838
			foreach ($config['installedpackages']['package'] as $package) {
839
				if ($package['logging']) {
840
					array_push($separatelogfacilities, $package['logging']['facilityname']);
841
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
842
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
843
					}
844
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
845
				}
846
			}
847
		}
848
		$facilitylist = implode(',', array_unique($separatelogfacilities));
849
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
850
		if (!isset($syslogcfg['disablelocallogging'])) {
851
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
852
		}
853

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
976
		if (isset($syslogcfg['zmqserver'])) {
977
				$syslogconf .= <<<EOD
978
*.*								^{$syslogcfg['zmqserver']}
979

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

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

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

    
1013
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1014
	}
1015

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

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

    
1027

    
1028
	$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}");
1029

    
1030
	if (platform_booting()) {
1031
		echo gettext("done.") . "\n";
1032
	}
1033

    
1034
	return $retval;
1035
}
1036

    
1037
function system_webgui_create_certificate() {
1038
	global $config, $g;
1039

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

    
1050
	$cert = array();
1051
	$cert['refid'] = uniqid();
1052
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1053

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

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

    
1077
function system_webgui_start() {
1078
	global $config, $g;
1079

    
1080
	if (platform_booting()) {
1081
		echo gettext("Starting webConfigurator...");
1082
	}
1083

    
1084
	chdir($g['www_path']);
1085

    
1086
	/* defaults */
1087
	$portarg = "80";
1088
	$crt = "";
1089
	$key = "";
1090
	$ca = "";
1091

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

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

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

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

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

    
1120
	sleep(1);
1121

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

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

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

    
1135
	return $res;
1136
}
1137

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

    
1149
	global $config, $g;
1150

    
1151
	if (!is_dir("{$g['tmp_path']}/lighttpdcompress")) {
1152
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1153
	}
1154

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

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

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

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

    
1185
	if (empty($port)) {
1186
		$lighty_port = "80";
1187
	} else {
1188
		$lighty_port = $port;
1189
	}
1190

    
1191
	$memory = get_memory();
1192
	$realmem = $memory[1];
1193

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

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

    
1216
	} else {
1217
		if ($realmem < 78) {
1218
			$max_php_children = 0;
1219
		} else {
1220
			$max_php_children = 1;
1221
		}
1222
	}
1223

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

    
1231

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

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

    
1266
EOD;
1267
	}
1268

    
1269

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

    
1278
## FreeBSD!
1279
server.event-handler	= "freebsd-kqueue"
1280
server.network-backend 	= "writev"
1281
#server.use-ipv6 = "enable"
1282

    
1283
## modules to load
1284
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1285
	{$captiveportal}, "mod_fastcgi"
1286
)
1287

    
1288
server.max-keep-alive-requests = 15
1289
server.max-keep-alive-idle = 30
1290

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

    
1296
# Maximum idle time with nothing being written (php downloading)
1297
server.max-write-idle = 999
1298

    
1299
{$lighty_use_syslog}
1300

    
1301
# files to check for if .../ is requested
1302
server.indexfiles           = ( "index.php", "index.html",
1303
                                "index.htm", "default.htm" )
1304

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

    
1358
# Use the "Content-Type" extended attribute to obtain mime type if possible
1359
#mimetypes.use-xattr        = "enable"
1360

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

    
1368

    
1369
######### Options that are good to be but not necessary to be changed #######
1370

    
1371
## disable server header
1372
server.tag = ""
1373

    
1374
## bind to port (default: 80)
1375

    
1376
EOD;
1377

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

    
1393

    
1394
	$lighty_config .= <<<EOD
1395

    
1396
## error-handler for status 404
1397
#server.error-handler-404   = "/error-handler.html"
1398
#server.error-handler-404   = "/error-handler.php"
1399

    
1400
## to help the rc.scripts
1401
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1402

    
1403
## virtual directory listings
1404
server.dir-listing         = "disable"
1405

    
1406
## enable debugging
1407
debug.log-request-header   = "disable"
1408
debug.log-response-header  = "disable"
1409
debug.log-request-handling = "disable"
1410
debug.log-file-not-found   = "disable"
1411

    
1412
# gzip compression
1413
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1414
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1415

    
1416
{$server_upload_dirs}
1417

    
1418
{$server_max_request_size}
1419

    
1420
{$fastcgi_config}
1421

    
1422
{$cgi_config}
1423

    
1424
{$captive_portal_mod_evasive}
1425

    
1426
expire.url = (
1427
		"" => "access 50 hours",
1428
	)
1429

    
1430
EOD;
1431

    
1432
	$cert = str_replace("\r", "", $cert);
1433
	$key = str_replace("\r", "", $key);
1434
	$ca = str_replace("\r", "", $ca);
1435

    
1436
	$cert = str_replace("\n\n", "\n", $cert);
1437
	$key = str_replace("\n\n", "\n", $key);
1438
	$ca = str_replace("\n\n", "\n", $ca);
1439

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

    
1466
		// SSLv2/3 is deprecated, force use of TLS
1467
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1468
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1469

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

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

    
1475
		if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
1476
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1477
		}
1478
	}
1479

    
1480
	// Add HTTP to HTTPS redirect
1481
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1482
		if ($lighty_port != "443") {
1483
			$redirectport = ":{$lighty_port}";
1484
		}
1485
		$lighty_config .= <<<EOD
1486
\$SERVER["socket"] == ":80" {
1487
	\$HTTP["host"] =~ "(.*)" {
1488
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1489
	}
1490
}
1491
\$SERVER["socket"] == "[::]:80" {
1492
	\$HTTP["host"] =~ "(.*)" {
1493
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1494
	}
1495
}
1496
EOD;
1497
	}
1498

    
1499
	$fd = fopen("{$filename}", "w");
1500
	if (!$fd) {
1501
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1502
		return 1;
1503
	}
1504
	fwrite($fd, $lighty_config);
1505
	fclose($fd);
1506

    
1507
	return 0;
1508

    
1509
}
1510

    
1511
function system_timezone_configure() {
1512
	global $config, $g;
1513
	if (isset($config['system']['developerspew'])) {
1514
		$mt = microtime();
1515
		echo "system_timezone_configure() being called $mt\n";
1516
	}
1517

    
1518
	$syscfg = $config['system'];
1519

    
1520
	if (platform_booting()) {
1521
		echo gettext("Setting timezone...");
1522
	}
1523

    
1524
	/* extract appropriate timezone file */
1525
	$timezone = $syscfg['timezone'];
1526
	if ($timezone) {
1527
		exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
1528
		foreach ($tzs as $tz) {
1529
			if (preg_match(",{$timezone}$,", $tz)) {
1530
				break;
1531
			}
1532
			if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
1533
				$timezone = $matches[1];
1534
				break;
1535
			}
1536
		}
1537
	} else {
1538
		$timezone = "Etc/UTC";
1539
	}
1540

    
1541
	conf_mount_rw();
1542

    
1543
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1544
		escapeshellarg($timezone) . " > /etc/localtime");
1545

    
1546
	mwexec("sync");
1547
	conf_mount_ro();
1548

    
1549
	if (platform_booting()) {
1550
		echo gettext("done.") . "\n";
1551
	}
1552
}
1553

    
1554
function system_ntp_setup_gps($serialport) {
1555
	global $config, $g;
1556
	$gps_device = '/dev/gps0';
1557
	$serialport = '/dev/'.$serialport;
1558

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

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

    
1568
	$gpsbaud = '4800';
1569
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1570
		switch ($config['ntpd']['gps']['speed']) {
1571
			case '16':
1572
				$gpsbaud = '9600';
1573
				break;
1574
			case '32':
1575
				$gpsbaud = '19200';
1576
				break;
1577
			case '48':
1578
				$gpsbaud = '38400';
1579
				break;
1580
			case '64':
1581
				$gpsbaud = '57600';
1582
				break;
1583
			case '80':
1584
				$gpsbaud = '115200';
1585
				break;
1586
		}
1587
	}
1588

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

    
1592
	/* Send the following to the GPS port to initialize the GPS */
1593
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1594
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1595
	} else {
1596
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1597
	}
1598

    
1599
	/* XXX: Why not file_put_contents to the device */
1600
	@file_put_contents('/tmp/gps.init', $gps_init);
1601
	mwexec("cat /tmp/gps.init > {$serialport}");
1602

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

    
1608
	conf_mount_ro();
1609

    
1610
	return true;
1611
}
1612

    
1613
function system_ntp_setup_pps($serialport) {
1614
	global $config, $g;
1615

    
1616
	$pps_device = '/dev/pps0';
1617
	$serialport = '/dev/'.$serialport;
1618

    
1619
	if (!file_exists($serialport)) {
1620
		return false;
1621
	}
1622

    
1623
	conf_mount_rw();
1624
	// Create symlink that ntpd requires
1625
	unlink_if_exists($pps_device);
1626
	@symlink($serialport, $pps_device);
1627

    
1628
	conf_mount_ro();
1629

    
1630
	return true;
1631
}
1632

    
1633

    
1634
function system_ntp_configure($start_ntpd=true) {
1635
	global $config, $g;
1636

    
1637
	$driftfile = "/var/db/ntpd.drift";
1638
	$statsdir = "/var/log/ntp";
1639
	$gps_device = '/dev/gps0';
1640

    
1641
	if ($g['platform'] == 'jail') {
1642
		return;
1643
	}
1644

    
1645
	safe_mkdir($statsdir);
1646

    
1647
	if (!is_array($config['ntpd'])) {
1648
		$config['ntpd'] = array();
1649
	}
1650

    
1651
	$ntpcfg = "# \n";
1652
	$ntpcfg .= "# pfSense ntp configuration file \n";
1653
	$ntpcfg .= "# \n\n";
1654
	$ntpcfg .= "tinker panic 0 \n";
1655

    
1656
	/* Add Orphan mode */
1657
	$ntpcfg .= "# Orphan mode stratum\n";
1658
	$ntpcfg .= 'tos orphan ';
1659
	if (!empty($config['ntpd']['orphan'])) {
1660
		$ntpcfg .= $config['ntpd']['orphan'];
1661
	} else {
1662
		$ntpcfg .= '12';
1663
	}
1664
	$ntpcfg .= "\n";
1665

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

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

    
1777
	$ntpcfg .= "\n\n# Upstream Servers\n";
1778
	/* foreach through ntp servers and write out to ntpd.conf */
1779
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1780
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1781
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1782
			$ntpcfg .= ' prefer';
1783
		}
1784
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1785
			$ntpcfg .= ' noselect';
1786
		}
1787
		$ntpcfg .= "\n";
1788
	}
1789
	unset($ts);
1790

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

    
1858
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1859
	$ntpcfg .= "\n";
1860
	if (!empty($config['ntpd']['leapsec'])) {
1861
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1862
		file_put_contents('/var/db/leap-seconds', $leapsec);
1863
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1864
	}
1865

    
1866

    
1867
	if (empty($config['ntpd']['interface'])) {
1868
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1869
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1870
		} else {
1871
			$interfaces = array();
1872
		}
1873
	} else {
1874
		$interfaces = explode(",", $config['ntpd']['interface']);
1875
	}
1876

    
1877
	if (is_array($interfaces) && count($interfaces)) {
1878
		$ntpcfg .= "interface ignore all\n";
1879
		foreach ($interfaces as $interface) {
1880
			if (strstr($interface, "_vip")) {
1881
				$interface = get_configured_carp_interface_list($interface);
1882
			}
1883
			if (!is_ipaddr($interface)) {
1884
				$interface = get_real_interface($interface);
1885
			}
1886
			if (!empty($interface)) {
1887
				$ntpcfg .= "interface listen {$interface}\n";
1888
			}
1889
		}
1890
	}
1891

    
1892
	/* open configuration for writing or bail */
1893
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1894
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1895
		return;
1896
	}
1897

    
1898
	/* At bootup we just want to write out the config. */
1899
	if (!$start_ntpd) {
1900
		return;
1901
	}
1902

    
1903
	/* if ntpd is running, kill it */
1904
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1905
		killbypid("{$g['varrun_path']}/ntpd.pid");
1906
	}
1907
	@unlink("{$g['varrun_path']}/ntpd.pid");
1908

    
1909
	/* if /var/empty does not exist, create it */
1910
	if (!is_dir("/var/empty")) {
1911
		mkdir("/var/empty", 0775, true);
1912
	}
1913

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

    
1917
	// Note that we are starting up
1918
	log_error("NTPD is starting up.");
1919
	return;
1920
}
1921

    
1922
function sync_system_time() {
1923
	global $config, $g;
1924

    
1925
	if (platform_booting()) {
1926
		echo gettext("Syncing system time before startup...");
1927
	}
1928

    
1929
	/* foreach through servers and write out to ntpd.conf */
1930
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1931
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1932
	}
1933

    
1934
	if (platform_booting()) {
1935
		echo gettext("done.") . "\n";
1936
	}
1937

    
1938
}
1939

    
1940
function system_halt() {
1941
	global $g;
1942

    
1943
	system_reboot_cleanup();
1944

    
1945
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1946
}
1947

    
1948
function system_reboot() {
1949
	global $g;
1950

    
1951
	system_reboot_cleanup();
1952

    
1953
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1954
}
1955

    
1956
function system_reboot_sync() {
1957
	global $g;
1958

    
1959
	system_reboot_cleanup();
1960

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

    
1964
function system_reboot_cleanup() {
1965
	global $config, $cpzone;
1966

    
1967
	mwexec("/usr/local/bin/beep.sh stop");
1968
	require_once("captiveportal.inc");
1969
	if (is_array($config['captiveportal'])) {
1970
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1971
			captiveportal_radius_stop_all();
1972
			captiveportal_send_server_accounting(true);
1973
		}
1974
	}
1975
	require_once("voucher.inc");
1976
	voucher_save_db_to_config();
1977
	require_once("pkg-utils.inc");
1978
	stop_packages();
1979
}
1980

    
1981
function system_do_shell_commands($early = 0) {
1982
	global $config, $g;
1983
	if (isset($config['system']['developerspew'])) {
1984
		$mt = microtime();
1985
		echo "system_do_shell_commands() being called $mt\n";
1986
	}
1987

    
1988
	if ($early) {
1989
		$cmdn = "earlyshellcmd";
1990
	} else {
1991
		$cmdn = "shellcmd";
1992
	}
1993

    
1994
	if (is_array($config['system'][$cmdn])) {
1995

    
1996
		/* *cmd is an array, loop through */
1997
		foreach ($config['system'][$cmdn] as $cmd) {
1998
			exec($cmd);
1999
		}
2000

    
2001
	} elseif ($config['system'][$cmdn] <> "") {
2002

    
2003
		/* execute single item */
2004
		exec($config['system'][$cmdn]);
2005

    
2006
	}
2007
}
2008

    
2009
function system_console_configure() {
2010
	global $config, $g;
2011
	if (isset($config['system']['developerspew'])) {
2012
		$mt = microtime();
2013
		echo "system_console_configure() being called $mt\n";
2014
	}
2015

    
2016
	if (isset($config['system']['disableconsolemenu'])) {
2017
		touch("{$g['varetc_path']}/disableconsole");
2018
	} else {
2019
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
2020
	}
2021
}
2022

    
2023
function system_dmesg_save() {
2024
	global $g;
2025
	if (isset($config['system']['developerspew'])) {
2026
		$mt = microtime();
2027
		echo "system_dmesg_save() being called $mt\n";
2028
	}
2029

    
2030
	$dmesg = "";
2031
	$_gb = exec("/sbin/dmesg", $dmesg);
2032

    
2033
	/* find last copyright line (output from previous boots may be present) */
2034
	$lastcpline = 0;
2035

    
2036
	for ($i = 0; $i < count($dmesg); $i++) {
2037
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
2038
			$lastcpline = $i;
2039
		}
2040
	}
2041

    
2042
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
2043
	if (!$fd) {
2044
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
2045
		return 1;
2046
	}
2047

    
2048
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
2049
		fwrite($fd, $dmesg[$i] . "\n");
2050
	}
2051

    
2052
	fclose($fd);
2053
	unset($dmesg);
2054

    
2055
	return 0;
2056
}
2057

    
2058
function system_set_harddisk_standby() {
2059
	global $g, $config;
2060
	if (isset($config['system']['developerspew'])) {
2061
		$mt = microtime();
2062
		echo "system_set_harddisk_standby() being called $mt\n";
2063
	}
2064

    
2065
	if (isset($config['system']['harddiskstandby'])) {
2066
		if (platform_booting()) {
2067
			echo gettext('Setting hard disk standby... ');
2068
		}
2069

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

    
2090
function system_setup_sysctl() {
2091
	global $config;
2092
	if (isset($config['system']['developerspew'])) {
2093
		$mt = microtime();
2094
		echo "system_setup_sysctl() being called $mt\n";
2095
	}
2096

    
2097
	activate_sysctls();
2098

    
2099
	if (isset($config['system']['sharednet'])) {
2100
		system_disable_arp_wrong_if();
2101
	}
2102
}
2103

    
2104
function system_disable_arp_wrong_if() {
2105
	global $config;
2106
	if (isset($config['system']['developerspew'])) {
2107
		$mt = microtime();
2108
		echo "system_disable_arp_wrong_if() being called $mt\n";
2109
	}
2110
	set_sysctl(array(
2111
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2112
		"net.link.ether.inet.log_arp_movements" => "0"
2113
	));
2114
}
2115

    
2116
function system_enable_arp_wrong_if() {
2117
	global $config;
2118
	if (isset($config['system']['developerspew'])) {
2119
		$mt = microtime();
2120
		echo "system_enable_arp_wrong_if() being called $mt\n";
2121
	}
2122
	set_sysctl(array(
2123
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2124
		"net.link.ether.inet.log_arp_movements" => "1"
2125
	));
2126
}
2127

    
2128
function enable_watchdog() {
2129
	global $config;
2130
	return;
2131
	$install_watchdog = false;
2132
	$supported_watchdogs = array("Geode");
2133
	$file = file_get_contents("/var/log/dmesg.boot");
2134
	foreach ($supported_watchdogs as $sd) {
2135
		if (stristr($file, "Geode")) {
2136
			$install_watchdog = true;
2137
		}
2138
	}
2139
	if ($install_watchdog == true) {
2140
		if (is_process_running("watchdogd")) {
2141
			mwexec("/usr/bin/killall watchdogd", true);
2142
		}
2143
		exec("/usr/sbin/watchdogd");
2144
	}
2145
}
2146

    
2147
function system_check_reset_button() {
2148
	global $g;
2149

    
2150
	$specplatform = system_identify_specific_platform();
2151

    
2152
	switch ($specplatform['name']) {
2153
		case 'alix':
2154
		case 'wrap':
2155
		case 'FW7541':
2156
		case 'APU':
2157
		case 'RCC-VE':
2158
			break;
2159
		default:
2160
			return 0;
2161
	}
2162

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

    
2165
	if ($retval == 99) {
2166
		/* user has pressed reset button for 2 seconds -
2167
		   reset to factory defaults */
2168
		echo <<<EOD
2169

    
2170
***********************************************************************
2171
* Reset button pressed - resetting configuration to factory defaults. *
2172
* The system will reboot after this completes.                        *
2173
***********************************************************************
2174

    
2175

    
2176
EOD;
2177

    
2178
		reset_factory_defaults();
2179
		system_reboot_sync();
2180
		exit(0);
2181
	}
2182

    
2183
	return 0;
2184
}
2185

    
2186
/* attempt to identify the specific platform (for embedded systems)
2187
   Returns an array with two elements:
2188
	name => platform string (e.g. 'wrap', 'alix' etc.)
2189
	descr => human-readable description (e.g. "PC Engines WRAP")
2190
*/
2191
function system_identify_specific_platform() {
2192
	global $g;
2193

    
2194
	if ($g['platform'] == 'generic-pc') {
2195
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2196
	}
2197

    
2198
	if ($g['platform'] == 'generic-pc-cdrom') {
2199
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2200
	}
2201

    
2202
	/* Try to guess from smbios strings */
2203
	unset($output);
2204
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2205
	switch ($output[0]) {
2206
		case 'FW7541':
2207
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2208
			break;
2209
		case 'APU':
2210
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2211
			break;
2212
		case 'RCC-VE':
2213
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2214
			break;
2215
		case 'SYS-5018A-FTN4':
2216
		case 'A1SAi':
2217
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2218
			break;
2219
	}
2220

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

    
2226
	$dmesg = get_single_sysctl('hw.model');
2227

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

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

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

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

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

    
2248
	unset($dmesg);
2249

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

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

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

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

    
2266
?>
(53-53/68)