Project

General

Profile

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

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

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

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

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

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

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

    
41
function activate_powerd() {
42
	global $config, $g;
43

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

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

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

    
62
		$normal_mode = "hadp";
63
		if (!empty($config['system']['powerd_normal_mode'])) {
64
			$normal_mode = $config['system']['powerd_normal_mode'];
65
		}
66

    
67
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
68
	}
69
}
70

    
71
function get_default_sysctl_value($id) {
72
	global $sysctls;
73

    
74
	if (isset($sysctls[$id])) {
75
		return $sysctls[$id];
76
	}
77
}
78

    
79
function get_sysctl_descr($sysctl) {
80
	unset($output);
81
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
82

    
83
	return $output[0];
84
}
85

    
86
function system_get_sysctls() {
87
	global $config, $sysctls;
88

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

    
99
			$disp_sysctl[$id] = $tunable;
100
			$disp_sysctl[$id]['modified'] = true;
101
			$disp_cache[$tunable['tunable']] = 'set';
102
		}
103
	}
104

    
105
	foreach ($sysctls as $sysctl => $value) {
106
		if (isset($disp_cache[$sysctl])) {
107
			continue;
108
		}
109

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

    
116
function activate_sysctls() {
117
	global $config, $g, $sysctls;
118

    
119
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
120
		foreach ($config['sysctl']['item'] as $tunable) {
121
			if ($tunable['value'] == "default") {
122
				$value = get_default_sysctl_value($tunable['tunable']);
123
			} else {
124
				$value = $tunable['value'];
125
			}
126

    
127
			$sysctls[$tunable['tunable']] = $value;
128
		}
129
	}
130

    
131
	set_sysctl($sysctls);
132
}
133

    
134
function system_resolvconf_generate($dynupdate = false) {
135
	global $config, $g;
136

    
137
	if (isset($config['system']['developerspew'])) {
138
		$mt = microtime();
139
		echo "system_resolvconf_generate() being called $mt\n";
140
	}
141

    
142
	$syscfg = $config['system'];
143

    
144
	if ((((isset($config['dnsmasq']['enable'])) &&
145
	      (!isset($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
146
	      (empty($config['dnsmasq']['interface']) ||
147
	       in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
148
	     ((isset($config['unbound']['enable'])) &&
149
	      (!isset($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
150
	      (empty($config['unbound']['active_interface']) ||
151
	       in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
152
	       in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
153
	     (!isset($config['system']['dnslocalhost']))) {
154
		$resolvconf .= "nameserver 127.0.0.1\n";
155
	}
156

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

    
186
	// Add EDNS support
187
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
188
		$resolvconf .= "options edns0\n";
189
	}
190

    
191
	$dnslock = lock('resolvconf', LOCK_EX);
192

    
193
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
194
	if (!$fd) {
195
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
196
		unlock($dnslock);
197
		return 1;
198
	}
199

    
200
	fwrite($fd, $resolvconf);
201
	fclose($fd);
202

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

    
212
	if (!platform_booting()) {
213
		/* restart dhcpd (nameservers may have changed) */
214
		if (!$dynupdate) {
215
			services_dhcpd_configure();
216
		}
217
	}
218

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

    
249
	unlock($dnslock);
250

    
251
	return 0;
252
}
253

    
254
function get_searchdomains() {
255
	global $config, $g;
256

    
257
	$master_list = array();
258

    
259
	// Read in dhclient nameservers
260
	$search_list = glob("/var/etc/searchdomain_*");
261
	if (is_array($search_list)) {
262
		foreach ($search_list as $fdns) {
263
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
264
			if (!is_array($contents)) {
265
				continue;
266
			}
267
			foreach ($contents as $dns) {
268
				if (is_hostname($dns)) {
269
					$master_list[] = $dns;
270
				}
271
			}
272
		}
273
	}
274

    
275
	return $master_list;
276
}
277

    
278
function get_nameservers() {
279
	global $config, $g;
280
	$master_list = array();
281

    
282
	// Read in dhclient nameservers
283
	$dns_lists = glob("/var/etc/nameserver_*");
284
	if (is_array($dns_lists)) {
285
		foreach ($dns_lists as $fdns) {
286
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
287
			if (!is_array($contents)) {
288
				continue;
289
			}
290
			foreach ($contents as $dns) {
291
				if (is_ipaddr($dns)) {
292
					$master_list[] = $dns;
293
				}
294
			}
295
		}
296
	}
297

    
298
	// Read in any extra nameservers
299
	if (file_exists("/var/etc/nameservers.conf")) {
300
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
301
		if (is_array($dns_s)) {
302
			foreach ($dns_s as $dns) {
303
				if (is_ipaddr($dns)) {
304
					$master_list[] = $dns;
305
				}
306
			}
307
		}
308
	}
309

    
310
	return $master_list;
311
}
312

    
313
function system_hosts_generate() {
314
	global $config, $g;
315
	if (isset($config['system']['developerspew'])) {
316
		$mt = microtime();
317
		echo "system_hosts_generate() being called $mt\n";
318
	}
319

    
320
	$syscfg = $config['system'];
321
	if (isset($config['unbound']) && isset($config['unbound']['enable'])) {
322
		$dnsmasqcfg = $config['unbound'];
323
	} else {
324
		$dnsmasqcfg = $config['dnsmasq'];
325
	}
326

    
327
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
328
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
329
	$lhosts = "";
330
	$dhosts = "";
331

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

    
363
	if (isset($dnsmasqcfg['enable'])) {
364
		if (!is_array($dnsmasqcfg['hosts'])) {
365
			$dnsmasqcfg['hosts'] = array();
366
		}
367

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

    
416
		if (isset($dnsmasqcfg['dhcpfirst'])) {
417
			$hosts .= $dhosts . $lhosts;
418
		} else {
419
			$hosts .= $lhosts . $dhosts;
420
		}
421
	}
422

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

    
439
	if (isset($config['unbound']['enable'])) {
440
		require_once("unbound.inc");
441
		unbound_hosts_generate();
442
	}
443

    
444
	return 0;
445
}
446

    
447
function system_dhcpleases_configure() {
448
	global $config, $g;
449

    
450
	/* Start the monitoring process for dynamic dhcpclients. */
451
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
452
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
453
		/* Make sure we do not error out */
454
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
455
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
456
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
457
		}
458

    
459
		if (isset($config['unbound']['enable'])) {
460
			$dns_pid = "unbound.pid";
461
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
462
		} else {
463
			$dns_pid = "dnsmasq.pid";
464
			$unbound_conf = "";
465
		}
466

    
467
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
468
		if (isvalidpid($pidfile)) {
469
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
470
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
471
			if (intval($retval) == 0) {
472
				sigkillbypid($pidfile, "HUP");
473
				return;
474
			} else {
475
				sigkillbypid($pidfile, "TERM");
476
			}
477
		}
478

    
479
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
480
		if (is_process_running("dhcpleases")) {
481
			sigkillbyname('dhcpleases', "TERM");
482
		}
483
		@unlink($pidfile);
484
		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");
485
	} else {
486
		sigkillbypid($pidfile, "TERM");
487
		@unlink($pidfile);
488
	}
489
}
490

    
491
function system_hostname_configure() {
492
	global $config, $g;
493
	if (isset($config['system']['developerspew'])) {
494
		$mt = microtime();
495
		echo "system_hostname_configure() being called $mt\n";
496
	}
497

    
498
	$syscfg = $config['system'];
499

    
500
	/* set hostname */
501
	$status = mwexec("/bin/hostname " .
502
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
503

    
504
	/* Setup host GUID ID.  This is used by ZFS. */
505
	mwexec("/etc/rc.d/hostid start");
506

    
507
	return $status;
508
}
509

    
510
function system_routing_configure($interface = "") {
511
	global $config, $g;
512

    
513
	if (isset($config['system']['developerspew'])) {
514
		$mt = microtime();
515
		echo "system_routing_configure() being called $mt\n";
516
	}
517

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

    
589
	if ($dont_add_route == false) {
590
		if (!empty($interface) && $interface != $interfacegw) {
591
			;
592
		} else if (is_ipaddrv4($gatewayip)) {
593
			log_error("ROUTING: setting default route to $gatewayip");
594
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
595
		}
596

    
597
		if (!empty($interface) && $interface != $interfacegwv6) {
598
			;
599
		} else if (is_ipaddrv6($gatewayipv6)) {
600
			$ifscope = "";
601
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
602
				$ifscope = "%{$defaultifv6}";
603
			}
604
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
605
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
606
		}
607
	}
608

    
609
	system_staticroutes_configure($interface, false);
610

    
611
	return 0;
612
}
613

    
614
function system_staticroutes_configure($interface = "", $update_dns = false) {
615
	global $config, $g, $aliastable;
616

    
617
	$filterdns_list = array();
618

    
619
	$static_routes = get_staticroutes(false, true);
620
	if (count($static_routes)) {
621
		$gateways_arr = return_gateways_array(false, true);
622

    
623
		foreach ($static_routes as $rtent) {
624
			if (empty($gateways_arr[$rtent['gateway']])) {
625
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
626
				continue;
627
			}
628
			$gateway = $gateways_arr[$rtent['gateway']];
629
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
630
				continue;
631
			}
632

    
633
			$gatewayip = $gateway['gateway'];
634
			$interfacegw = $gateway['interface'];
635

    
636
			$blackhole = "";
637
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
638
				$blackhole = "-blackhole";
639
			}
640

    
641
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
642
				continue;
643
			}
644

    
645
			$dnscache = array();
646
			if ($update_dns === true) {
647
				if (is_subnet($rtent['network'])) {
648
					continue;
649
				}
650
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
651
				if (empty($dnscache)) {
652
					continue;
653
				}
654
			}
655

    
656
			if (is_subnet($rtent['network'])) {
657
				$ips = array($rtent['network']);
658
			} else {
659
				if (!isset($rtent['disabled'])) {
660
					$filterdns_list[] = $rtent['network'];
661
				}
662
				$ips = add_hostname_to_watch($rtent['network']);
663
			}
664

    
665
			foreach ($dnscache as $ip) {
666
				if (in_array($ip, $ips)) {
667
					continue;
668
				}
669
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
670
				if (isset($config['system']['route-debug'])) {
671
					$mt = microtime();
672
					log_error("ROUTING debug: $mt - route delete $ip ");
673
				}
674
			}
675

    
676
			if (isset($rtent['disabled'])) {
677
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
678
				foreach ($ips as $ip) {
679
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
680
					if (isset($config['system']['route-debug'])) {
681
						$mt = microtime();
682
						log_error("ROUTING debug: $mt - route delete $ip ");
683
					}
684
				}
685
				continue;
686
			}
687

    
688
			foreach ($ips as $ip) {
689
				if (is_ipaddrv4($ip)) {
690
					$ip .= "/32";
691
				}
692
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
693

    
694
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
695

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

    
698
				if (is_subnet($ip)) {
699
					if (is_ipaddr($gatewayip)) {
700
						mwexec($cmd . escapeshellarg($gatewayip));
701
						if (isset($config['system']['route-debug'])) {
702
							$mt = microtime();
703
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
704
						}
705
					} else if (!empty($interfacegw)) {
706
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
707
						if (isset($config['system']['route-debug'])) {
708
							$mt = microtime();
709
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
710
						}
711
					}
712
				}
713
			}
714
		}
715
		unset($gateways_arr);
716
	}
717
	unset($static_routes);
718

    
719
	if ($update_dns === false) {
720
		if (count($filterdns_list)) {
721
			$interval = 60;
722
			$hostnames = "";
723
			array_unique($filterdns_list);
724
			foreach ($filterdns_list as $hostname) {
725
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
726
			}
727
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
728
			unset($hostnames);
729

    
730
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
731
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
732
			} else {
733
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
734
			}
735
		} else {
736
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
737
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
738
		}
739
	}
740
	unset($filterdns_list);
741

    
742
	return 0;
743
}
744

    
745
function system_routing_enable() {
746
	global $config, $g;
747
	if (isset($config['system']['developerspew'])) {
748
		$mt = microtime();
749
		echo "system_routing_enable() being called $mt\n";
750
	}
751

    
752
	set_sysctl(array(
753
		"net.inet.ip.forwarding" => "1",
754
		"net.inet6.ip6.forwarding" => "1"
755
	));
756

    
757
	return;
758
}
759

    
760
function system_syslogd_fixup_server($server) {
761
	/* If it's an IPv6 IP alone, encase it in brackets */
762
	if (is_ipaddrv6($server)) {
763
		return "[$server]";
764
	} else {
765
		return $server;
766
	}
767
}
768

    
769
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
770
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
771
	$facility .= " ".
772
	$remote_servers = "";
773
	$pad_to = 56;
774
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
775
	if ($syslogcfg['remoteserver']) {
776
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
777
	}
778
	if ($syslogcfg['remoteserver2']) {
779
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
780
	}
781
	if ($syslogcfg['remoteserver3']) {
782
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
783
	}
784
	return $remote_servers;
785
}
786

    
787
function system_syslogd_start() {
788
	global $config, $g;
789
	if (isset($config['system']['developerspew'])) {
790
		$mt = microtime();
791
		echo "system_syslogd_start() being called $mt\n";
792
	}
793

    
794
	mwexec("/etc/rc.d/hostid start");
795

    
796
	$syslogcfg = $config['syslog'];
797

    
798
	if (platform_booting()) {
799
		echo gettext("Starting syslog...");
800
	}
801

    
802
	if (is_process_running("fifolog_writer")) {
803
		mwexec('/bin/pkill fifolog_writer');
804
	}
805

    
806
	// Which logging type are we using this week??
807
	if (isset($config['system']['disablesyslogclog'])) {
808
		$log_directive = "";
809
		$log_create_directive = "/usr/bin/touch ";
810
		$log_size = "";
811
	} else if (isset($config['system']['usefifolog'])) {
812
		$log_directive = "|/usr/sbin/fifolog_writer ";
813
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
814
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
815
	} else { // Defaults to CLOG
816
		$log_directive = "%";
817
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
818
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
819
	}
820

    
821
	$syslogd_extra = "";
822
	if (isset($syslogcfg)) {
823
		$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');
824
		$syslogconf = "";
825
		if ($config['installedpackages']['package']) {
826
			foreach ($config['installedpackages']['package'] as $package) {
827
				if ($package['logging']) {
828
					array_push($separatelogfacilities, $package['logging']['facilityname']);
829
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
830
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
831
					}
832
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
833
				}
834
			}
835
		}
836
		$facilitylist = implode(',', array_unique($separatelogfacilities));
837
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
838
		if (!isset($syslogcfg['disablelocallogging'])) {
839
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
840
		}
841

    
842
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
843
		if (!isset($syslogcfg['disablelocallogging'])) {
844
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
845
		}
846

    
847
		$syslogconf .= "!ppp\n";
848
		if (!isset($syslogcfg['disablelocallogging'])) {
849
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
850
		}
851

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

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

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

    
867
		$syslogconf .= "!charon,ipsec_starter\n";
868
		if (!isset($syslogcfg['disablelocallogging'])) {
869
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
870
		}
871
		if (isset($syslogcfg['vpn'])) {
872
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
873
		}
874

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

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

    
891
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
892
		if (!isset($syslogcfg['disablelocallogging'])) {
893
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
894
		}
895

    
896
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
897
		if (!isset($syslogcfg['disablelocallogging'])) {
898
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
899
		}
900
		if (isset($syslogcfg['dhcp'])) {
901
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
902
		}
903

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

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

    
920
		$syslogconf .= "!filterlog\n";
921
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
922
		if (isset($syslogcfg['filter'])) {
923
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
924
		}
925

    
926
		$syslogconf .= "!-{$facilitylist}\n";
927
		if (!isset($syslogcfg['disablelocallogging'])) {
928
			$syslogconf .= <<<EOD
929
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
930
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
931
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
932
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
933
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
934
local7.none							{$log_directive}{$g['varlog_path']}/system.log
935
security.*							{$log_directive}{$g['varlog_path']}/system.log
936
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
937
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
938
*.emerg								*
939

    
940
EOD;
941
		}
942
		if (isset($syslogcfg['vpn'])) {
943
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
944
		}
945
		if (isset($syslogcfg['portalauth'])) {
946
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
947
		}
948
		if (isset($syslogcfg['dhcp'])) {
949
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
950
		}
951
		if (isset($syslogcfg['system'])) {
952
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
953
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
954
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
955
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
956
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
957
		}
958
		if (isset($syslogcfg['logall'])) {
959
			// Make everything mean everything, including facilities excluded above.
960
			$syslogconf .= "!*\n";
961
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
962
		}
963

    
964
		if (isset($syslogcfg['zmqserver'])) {
965
				$syslogconf .= <<<EOD
966
*.*								^{$syslogcfg['zmqserver']}
967

    
968
EOD;
969
		}
970
		/* write syslog.conf */
971
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
972
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
973
			unset($syslogconf);
974
			return 1;
975
		}
976
		unset($syslogconf);
977

    
978
		// Ensure that the log directory exists
979
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
980
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
981
		}
982

    
983
		$sourceip = "";
984
		if (!empty($syslogcfg['sourceip'])) {
985
			if ($syslogcfg['ipproto'] == "ipv6") {
986
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
987
				if (!is_ipaddr($ifaddr)) {
988
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
989
				}
990
			} else {
991
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
992
				if (!is_ipaddr($ifaddr)) {
993
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
994
				}
995
			}
996
			if (is_ipaddr($ifaddr)) {
997
				$sourceip = "-b {$ifaddr}";
998
			}
999
		}
1000

    
1001
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1002
	}
1003

    
1004
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1005
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1006
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1007
	}
1008

    
1009
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1010
		// if it still hasn't responded to the TERM, KILL it.
1011
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1012
		usleep(100000);
1013
	}
1014

    
1015

    
1016
	$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}");
1017

    
1018
	if (platform_booting()) {
1019
		echo gettext("done.") . "\n";
1020
	}
1021

    
1022
	return $retval;
1023
}
1024

    
1025
function system_webgui_create_certificate() {
1026
	global $config, $g;
1027

    
1028
	if (!is_array($config['ca'])) {
1029
		$config['ca'] = array();
1030
	}
1031
	$a_ca =& $config['ca'];
1032
	if (!is_array($config['cert'])) {
1033
		$config['cert'] = array();
1034
	}
1035
	$a_cert =& $config['cert'];
1036
	log_error("Creating SSL Certificate for this host");
1037

    
1038
	$cert = array();
1039
	$cert['refid'] = uniqid();
1040
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1041

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

    
1059
	$a_cert[] = $cert;
1060
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1061
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
1062
	return $cert;
1063
}
1064

    
1065
function system_webgui_start() {
1066
	global $config, $g;
1067

    
1068
	if (platform_booting()) {
1069
		echo gettext("Starting webConfigurator...");
1070
	}
1071

    
1072
	chdir($g['www_path']);
1073

    
1074
	/* defaults */
1075
	$portarg = "80";
1076
	$crt = "";
1077
	$key = "";
1078
	$ca = "";
1079

    
1080
	/* non-standard port? */
1081
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1082
		$portarg = "{$config['system']['webgui']['port']}";
1083
	}
1084

    
1085
	if ($config['system']['webgui']['protocol'] == "https") {
1086
		// Ensure that we have a webConfigurator CERT
1087
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1088
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1089
			$cert = system_webgui_create_certificate();
1090
		}
1091
		$crt = base64_decode($cert['crt']);
1092
		$key = base64_decode($cert['prv']);
1093

    
1094
		if (!$config['system']['webgui']['port']) {
1095
			$portarg = "443";
1096
		}
1097
		$ca = ca_chain($cert);
1098
	}
1099

    
1100
	/* generate lighttpd configuration */
1101
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
1102
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
1103
		"cert.pem", "ca.pem");
1104

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

    
1108
	sleep(1);
1109

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

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

    
1115
	if (platform_booting()) {
1116
		if ($res == 0) {
1117
			echo gettext("done.") . "\n";
1118
		} else {
1119
			echo gettext("failed!") . "\n";
1120
		}
1121
	}
1122

    
1123
	return $res;
1124
}
1125

    
1126
function system_generate_lighty_config($filename,
1127
	$cert,
1128
	$key,
1129
	$ca,
1130
	$pid_file,
1131
	$port = 80,
1132
	$document_root = "/usr/local/www/",
1133
	$cert_location = "cert.pem",
1134
	$ca_location = "ca.pem",
1135
	$captive_portal = false) {
1136

    
1137
	global $config, $g;
1138

    
1139
	if (!is_dir("{$g['tmp_path']}/lighttpdcompress")) {
1140
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1141
	}
1142

    
1143
	if (isset($config['system']['developerspew'])) {
1144
		$mt = microtime();
1145
		echo "system_generate_lighty_config() being called $mt\n";
1146
	}
1147

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

    
1152
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1153
		if (empty($maxprocperip)) {
1154
			$maxprocperip = 10;
1155
		}
1156
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
1157

    
1158
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
1159
		if (!is_dir("{$g['tmp_path']}/captiveportal")) {
1160
			@mkdir("{$g['tmp_path']}/captiveportal", 0555);
1161
		}
1162
		$server_max_request_size = "server.max-request-size    = 384";
1163
		$cgi_config = "";
1164
	} else {
1165
		$captiveportal = ",\"mod_cgi\"";
1166
		$captive_portal_rewrite = "";
1167
		$captive_portal_mod_evasive = "";
1168
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
1169
		$server_max_request_size = "server.max-request-size    = 2097152";
1170
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
1171
	}
1172

    
1173
	if (empty($port)) {
1174
		$lighty_port = "80";
1175
	} else {
1176
		$lighty_port = $port;
1177
	}
1178

    
1179
	$memory = get_memory();
1180
	$realmem = $memory[1];
1181

    
1182
	// Determine web GUI process settings and take into account low memory systems
1183
	if ($realmem < 255) {
1184
		$max_procs = 1;
1185
	} else {
1186
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1187
	}
1188

    
1189
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
1190
	if ($captive_portal !== false) {
1191
		if ($realmem > 135 and $realmem < 256) {
1192
			$max_procs += 1; // 2 worker processes
1193
		} else if ($realmem > 255 and $realmem < 513) {
1194
			$max_procs += 2; // 3 worker processes
1195
		} else if ($realmem > 512) {
1196
			$max_procs += 4; // 6 worker processes
1197
		}
1198
		if ($max_procs > 1) {
1199
			$max_php_children = intval($max_procs/2);
1200
		} else {
1201
			$max_php_children = 1;
1202
		}
1203

    
1204
	} else {
1205
		if ($realmem < 78) {
1206
			$max_php_children = 0;
1207
		} else {
1208
			$max_php_children = 1;
1209
		}
1210
	}
1211

    
1212
	if (!isset($config['syslog']['nologlighttpd'])) {
1213
		$lighty_use_syslog = <<<EOD
1214
## where to send error-messages to
1215
server.errorlog-use-syslog="enable"
1216
EOD;
1217
	}
1218

    
1219

    
1220
	if ($captive_portal !== false) {
1221
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
1222
		$fastcgi_config = <<<EOD
1223
#### fastcgi module
1224
## read fastcgi.txt for more info
1225
fastcgi.server = ( ".php" =>
1226
	( "localhost" =>
1227
		(
1228
			"socket" => "{$fast_cgi_path}",
1229
			"max-procs" => {$max_procs},
1230
			"bin-environment" => (
1231
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
1232
				"PHP_FCGI_MAX_REQUESTS" => "500"
1233
			),
1234
			"bin-path" => "/usr/local/bin/php-cgi"
1235
		)
1236
	)
1237
)
1238

    
1239
EOD;
1240
	} else {
1241
		$fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
1242
		$fastcgi_config = <<<EOD
1243
#### fastcgi module
1244
## read fastcgi.txt for more info
1245
fastcgi.server = ( ".php" =>
1246
	( "localhost" =>
1247
		(
1248
			"socket" => "{$fast_cgi_path}",
1249
			"broken-scriptfilename" => "enable"
1250
		)
1251
	)
1252
)
1253

    
1254
EOD;
1255
	}
1256

    
1257

    
1258
	$lighty_config = <<<EOD
1259
#
1260
# lighttpd configuration file
1261
#
1262
# use a it as base for lighttpd 1.0.0 and above
1263
#
1264
############ Options you really have to take care of ####################
1265

    
1266
## FreeBSD!
1267
server.event-handler	= "freebsd-kqueue"
1268
server.network-backend 	= "writev"
1269
#server.use-ipv6 = "enable"
1270

    
1271
## modules to load
1272
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1273
	{$captiveportal}, "mod_fastcgi"
1274
)
1275

    
1276
server.max-keep-alive-requests = 15
1277
server.max-keep-alive-idle = 30
1278

    
1279
## a static document-root, for virtual-hosting take look at the
1280
## server.virtual-* options
1281
server.document-root        = "{$document_root}"
1282
{$captive_portal_rewrite}
1283

    
1284
# Maximum idle time with nothing being written (php downloading)
1285
server.max-write-idle = 999
1286

    
1287
{$lighty_use_syslog}
1288

    
1289
# files to check for if .../ is requested
1290
server.indexfiles           = ( "index.php", "index.html",
1291
                                "index.htm", "default.htm" )
1292

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

    
1347
# Use the "Content-Type" extended attribute to obtain mime type if possible
1348
#mimetypes.use-xattr        = "enable"
1349

    
1350
## deny access the file-extensions
1351
#
1352
# ~    is for backupfiles from vi, emacs, joe, ...
1353
# .inc is often used for code includes which should in general not be part
1354
#      of the document-root
1355
url.access-deny             = ( "~", ".inc" )
1356

    
1357

    
1358
######### Options that are good to be but not necessary to be changed #######
1359

    
1360
## disable server header
1361
server.tag = ""
1362

    
1363
## bind to port (default: 80)
1364

    
1365
EOD;
1366

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

    
1382

    
1383
	$lighty_config .= <<<EOD
1384

    
1385
## error-handler for status 404
1386
#server.error-handler-404   = "/error-handler.html"
1387
#server.error-handler-404   = "/error-handler.php"
1388

    
1389
## to help the rc.scripts
1390
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1391

    
1392
## virtual directory listings
1393
server.dir-listing         = "disable"
1394

    
1395
## enable debugging
1396
debug.log-request-header   = "disable"
1397
debug.log-response-header  = "disable"
1398
debug.log-request-handling = "disable"
1399
debug.log-file-not-found   = "disable"
1400

    
1401
# gzip compression
1402
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1403
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1404

    
1405
{$server_upload_dirs}
1406

    
1407
{$server_max_request_size}
1408

    
1409
{$fastcgi_config}
1410

    
1411
{$cgi_config}
1412

    
1413
{$captive_portal_mod_evasive}
1414

    
1415
expire.url = (
1416
		"" => "access 50 hours",
1417
	)
1418

    
1419
EOD;
1420

    
1421
	$cert = str_replace("\r", "", $cert);
1422
	$key = str_replace("\r", "", $key);
1423
	$ca = str_replace("\r", "", $ca);
1424

    
1425
	$cert = str_replace("\n\n", "\n", $cert);
1426
	$key = str_replace("\n\n", "\n", $key);
1427
	$ca = str_replace("\n\n", "\n", $ca);
1428

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

    
1455
		// SSLv2/3 is deprecated, force use of TLS
1456
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1457
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1458

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

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

    
1464
		if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
1465
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1466
		}
1467
	}
1468

    
1469
	// Add HTTP to HTTPS redirect
1470
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1471
		if ($lighty_port != "443") {
1472
			$redirectport = ":{$lighty_port}";
1473
		}
1474
		$lighty_config .= <<<EOD
1475
\$SERVER["socket"] == ":80" {
1476
	\$HTTP["host"] =~ "(.*)" {
1477
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1478
	}
1479
}
1480
\$SERVER["socket"] == "[::]:80" {
1481
	\$HTTP["host"] =~ "(.*)" {
1482
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1483
	}
1484
}
1485
EOD;
1486
	}
1487

    
1488
	$fd = fopen("{$filename}", "w");
1489
	if (!$fd) {
1490
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1491
		return 1;
1492
	}
1493
	fwrite($fd, $lighty_config);
1494
	fclose($fd);
1495

    
1496
	return 0;
1497

    
1498
}
1499

    
1500
function system_get_timezone_list() {
1501
	global $g;
1502

    
1503
	$file_list = array_merge(
1504
		glob("/usr/share/zoneinfo/[A-Z]*"),
1505
		glob("/usr/share/zoneinfo/*/*"),
1506
		glob("/usr/share/zoneinfo/*/*/*")
1507
	);
1508

    
1509
	if (empty($file_list)) {
1510
		$file_list[] = $g['default_timezone'];
1511
	} else {
1512
		/* Remove directories from list */
1513
		$file_list = array_filter($file_list, function($v) {
1514
			return !is_dir($v);
1515
		});
1516
	}
1517

    
1518
	/* Remove directory prefix */
1519
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1520

    
1521
	sort($file_list);
1522

    
1523
	return $file_list;
1524
}
1525

    
1526
function system_timezone_configure() {
1527
	global $config, $g;
1528
	if (isset($config['system']['developerspew'])) {
1529
		$mt = microtime();
1530
		echo "system_timezone_configure() being called $mt\n";
1531
	}
1532

    
1533
	$syscfg = $config['system'];
1534

    
1535
	if (platform_booting()) {
1536
		echo gettext("Setting timezone...");
1537
	}
1538

    
1539
	/* extract appropriate timezone file */
1540
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1541
	conf_mount_rw();
1542
	/* DO NOT remove \n otherwise tzsetup will fail */
1543
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1544
	mwexec("/usr/sbin/tzsetup -r");
1545
	conf_mount_ro();
1546

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

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

    
1557
	if (!file_exists($serialport)) {
1558
		return false;
1559
	}
1560

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

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

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

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

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

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

    
1606
	conf_mount_ro();
1607

    
1608
	return true;
1609
}
1610

    
1611
function system_ntp_setup_pps($serialport) {
1612
	global $config, $g;
1613

    
1614
	$pps_device = '/dev/pps0';
1615
	$serialport = '/dev/'.$serialport;
1616

    
1617
	if (!file_exists($serialport)) {
1618
		return false;
1619
	}
1620

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

    
1626
	conf_mount_ro();
1627

    
1628
	return true;
1629
}
1630

    
1631

    
1632
function system_ntp_configure($start_ntpd=true) {
1633
	global $config, $g;
1634

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

    
1639
	safe_mkdir($statsdir);
1640

    
1641
	if (!is_array($config['ntpd'])) {
1642
		$config['ntpd'] = array();
1643
	}
1644

    
1645
	$ntpcfg = "# \n";
1646
	$ntpcfg .= "# pfSense ntp configuration file \n";
1647
	$ntpcfg .= "# \n\n";
1648
	$ntpcfg .= "tinker panic 0 \n";
1649

    
1650
	/* Add Orphan mode */
1651
	$ntpcfg .= "# Orphan mode stratum\n";
1652
	$ntpcfg .= 'tos orphan ';
1653
	if (!empty($config['ntpd']['orphan'])) {
1654
		$ntpcfg .= $config['ntpd']['orphan'];
1655
	} else {
1656
		$ntpcfg .= '12';
1657
	}
1658
	$ntpcfg .= "\n";
1659

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

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

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

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

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

    
1864

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

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

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

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

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

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

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

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

    
1920
function sync_system_time() {
1921
	global $config, $g;
1922

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

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

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

    
1936
}
1937

    
1938
function system_halt() {
1939
	global $g;
1940

    
1941
	system_reboot_cleanup();
1942

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

    
1946
function system_reboot() {
1947
	global $g;
1948

    
1949
	system_reboot_cleanup();
1950

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

    
1954
function system_reboot_sync() {
1955
	global $g;
1956

    
1957
	system_reboot_cleanup();
1958

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

    
1962
function system_reboot_cleanup() {
1963
	global $config, $cpzone;
1964

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

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

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

    
1992
	if (is_array($config['system'][$cmdn])) {
1993

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

    
1999
	} elseif ($config['system'][$cmdn] <> "") {
2000

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

    
2004
	}
2005
}
2006

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

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

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

    
2028
	$dmesg = "";
2029
	$_gb = exec("/sbin/dmesg", $dmesg);
2030

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

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

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

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

    
2050
	fclose($fd);
2051
	unset($dmesg);
2052

    
2053
	return 0;
2054
}
2055

    
2056
function system_set_harddisk_standby() {
2057
	global $g, $config;
2058

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

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

    
2069
		$standby = $config['system']['harddiskstandby'];
2070
		// Check for a numeric value
2071
		if (is_numeric($standby)) {
2072
			// Get only suitable candidates for standby; using get_smart_drive_list()
2073
			// from utils.inc to get the list of drives.
2074
			$harddisks = get_smart_drive_list();
2075

    
2076
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
2077
			// just in case of some weird pfSense platform installs.
2078
			if (count($harddisks) > 0) {
2079
				// Iterate disks and run the camcontrol command for each
2080
				foreach ($harddisks as $harddisk) {
2081
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
2082
				}
2083
				if (platform_booting()) {
2084
					echo gettext("done.") . "\n";
2085
				}
2086
			} else if (platform_booting()) {
2087
				echo gettext("failed!") . "\n";
2088
			}
2089
		} else if (platform_booting()) {
2090
			echo gettext("failed!") . "\n";
2091
		}
2092
	}
2093
}
2094

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

    
2102
	activate_sysctls();
2103

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

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

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

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

    
2152
function system_check_reset_button() {
2153
	global $g;
2154

    
2155
	$specplatform = system_identify_specific_platform();
2156

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

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

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

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

    
2181

    
2182
EOD;
2183

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

    
2189
	return 0;
2190
}
2191

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

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

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

    
2208
	/* Try to guess from smbios strings */
2209
	unset($output);
2210
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2211
	switch ($output[0]) {
2212
		case 'FW7541':
2213
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2214
			break;
2215
		case 'APU':
2216
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2217
			break;
2218
		case 'RCC-VE':
2219
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2220
			break;
2221
		case 'DFFv2':
2222
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2223
			break;
2224
		case 'SYS-5018A-FTN4':
2225
		case 'A1SAi':
2226
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2227
			break;
2228
		case 'SYS-5018D-FN4T':
2229
			return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
2230
			break;
2231
	}
2232

    
2233
	/* the rest of the code only deals with 'embedded' platforms */
2234
	if ($g['platform'] != 'nanobsd') {
2235
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2236
	}
2237

    
2238
	$dmesg = get_single_sysctl('hw.model');
2239

    
2240
	if (strpos($dmesg, "PC Engines WRAP") !== false) {
2241
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2242
	}
2243

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

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

    
2252
	if (preg_match("/Soekris net48../", $dmesg, $matches)) {
2253
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2254
	}
2255

    
2256
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2257
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2258
	}
2259

    
2260
	unset($dmesg);
2261

    
2262
	$dmesg_boot = system_get_dmesg_boot();
2263
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2264
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2265
	}
2266
	unset($dmesg_boot);
2267

    
2268
	/* unknown embedded platform */
2269
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2270
}
2271

    
2272
function system_get_dmesg_boot() {
2273
	global $g;
2274

    
2275
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2276
}
2277

    
2278
?>
(52-52/65)