Project

General

Profile

Download (67.4 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
	);
1507

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

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

    
1520
	sort($file_list);
1521

    
1522
	return $file_list;
1523
}
1524

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1605
	conf_mount_ro();
1606

    
1607
	return true;
1608
}
1609

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

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

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

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

    
1625
	conf_mount_ro();
1626

    
1627
	return true;
1628
}
1629

    
1630

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

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

    
1638
	safe_mkdir($statsdir);
1639

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

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

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

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

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

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

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

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

    
1859

    
1860
	if (empty($config['ntpd']['interface'])) {
1861
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1862
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1863
		} else {
1864
			$interfaces = array();
1865
		}
1866
	} else {
1867
		$interfaces = explode(",", $config['ntpd']['interface']);
1868
	}
1869

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

    
1885
	/* open configuration for writing or bail */
1886
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1887
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1888
		return;
1889
	}
1890

    
1891
	/* At bootup we just want to write out the config. */
1892
	if (!$start_ntpd) {
1893
		return;
1894
	}
1895

    
1896
	/* if ntpd is running, kill it */
1897
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1898
		killbypid("{$g['varrun_path']}/ntpd.pid");
1899
	}
1900
	@unlink("{$g['varrun_path']}/ntpd.pid");
1901

    
1902
	/* if /var/empty does not exist, create it */
1903
	if (!is_dir("/var/empty")) {
1904
		mkdir("/var/empty", 0775, true);
1905
	}
1906

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

    
1910
	// Note that we are starting up
1911
	log_error("NTPD is starting up.");
1912
	return;
1913
}
1914

    
1915
function sync_system_time() {
1916
	global $config, $g;
1917

    
1918
	if (platform_booting()) {
1919
		echo gettext("Syncing system time before startup...");
1920
	}
1921

    
1922
	/* foreach through servers and write out to ntpd.conf */
1923
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1924
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1925
	}
1926

    
1927
	if (platform_booting()) {
1928
		echo gettext("done.") . "\n";
1929
	}
1930

    
1931
}
1932

    
1933
function system_halt() {
1934
	global $g;
1935

    
1936
	system_reboot_cleanup();
1937

    
1938
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1939
}
1940

    
1941
function system_reboot() {
1942
	global $g;
1943

    
1944
	system_reboot_cleanup();
1945

    
1946
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1947
}
1948

    
1949
function system_reboot_sync() {
1950
	global $g;
1951

    
1952
	system_reboot_cleanup();
1953

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

    
1957
function system_reboot_cleanup() {
1958
	global $config, $cpzone;
1959

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

    
1974
function system_do_shell_commands($early = 0) {
1975
	global $config, $g;
1976
	if (isset($config['system']['developerspew'])) {
1977
		$mt = microtime();
1978
		echo "system_do_shell_commands() being called $mt\n";
1979
	}
1980

    
1981
	if ($early) {
1982
		$cmdn = "earlyshellcmd";
1983
	} else {
1984
		$cmdn = "shellcmd";
1985
	}
1986

    
1987
	if (is_array($config['system'][$cmdn])) {
1988

    
1989
		/* *cmd is an array, loop through */
1990
		foreach ($config['system'][$cmdn] as $cmd) {
1991
			exec($cmd);
1992
		}
1993

    
1994
	} elseif ($config['system'][$cmdn] <> "") {
1995

    
1996
		/* execute single item */
1997
		exec($config['system'][$cmdn]);
1998

    
1999
	}
2000
}
2001

    
2002
function system_console_configure() {
2003
	global $config, $g;
2004
	if (isset($config['system']['developerspew'])) {
2005
		$mt = microtime();
2006
		echo "system_console_configure() being called $mt\n";
2007
	}
2008

    
2009
	if (isset($config['system']['disableconsolemenu'])) {
2010
		touch("{$g['varetc_path']}/disableconsole");
2011
	} else {
2012
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
2013
	}
2014
}
2015

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

    
2023
	$dmesg = "";
2024
	$_gb = exec("/sbin/dmesg", $dmesg);
2025

    
2026
	/* find last copyright line (output from previous boots may be present) */
2027
	$lastcpline = 0;
2028

    
2029
	for ($i = 0; $i < count($dmesg); $i++) {
2030
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
2031
			$lastcpline = $i;
2032
		}
2033
	}
2034

    
2035
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
2036
	if (!$fd) {
2037
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
2038
		return 1;
2039
	}
2040

    
2041
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
2042
		fwrite($fd, $dmesg[$i] . "\n");
2043
	}
2044

    
2045
	fclose($fd);
2046
	unset($dmesg);
2047

    
2048
	return 0;
2049
}
2050

    
2051
function system_set_harddisk_standby() {
2052
	global $g, $config;
2053

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

    
2059
	if (isset($config['system']['harddiskstandby'])) {
2060
		if (platform_booting()) {
2061
			echo gettext('Setting hard disk standby... ');
2062
		}
2063

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

    
2071
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
2072
			// just in case of some weird pfSense platform installs.
2073
			if (count($harddisks) > 0) {
2074
				// Iterate disks and run the camcontrol command for each
2075
				foreach ($harddisks as $harddisk) {
2076
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
2077
				}
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
		case 'RCC-DFF':
2159
			break;
2160
		default:
2161
			return 0;
2162
	}
2163

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

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

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

    
2176

    
2177
EOD;
2178

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

    
2184
	return 0;
2185
}
2186

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

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

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

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

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

    
2233
	$dmesg = get_single_sysctl('hw.model');
2234

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

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

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

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

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

    
2255
	unset($dmesg);
2256

    
2257
	$dmesg_boot = system_get_dmesg_boot();
2258
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2259
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2260
	}
2261
	unset($dmesg_boot);
2262

    
2263
	/* unknown embedded platform */
2264
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2265
}
2266

    
2267
function system_get_dmesg_boot() {
2268
	global $g;
2269

    
2270
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2271
}
2272

    
2273
?>
(53-53/67)