Project

General

Profile

Download (68.2 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
	$gateways_arr = return_gateways_array(false, true);
590
	foreach($gateways_arr as $gateway) {
591
		// setup static interface routes for nonlocal gateways
592
		if (isset($gateway["nonlocalgateway"])) {
593
			$srgatewayip = $gateway['gateway'];
594
			$srinterfacegw = $gateway['interface'];
595
			if (is_ipaddr($srgatewayip) && !empty($srinterfacegw)) {
596
				$inet = (!is_ipaddrv4($srgatewayip) ? "-inet6" : "-inet");
597
				$cmd = "/sbin/route change {$inet} " . escapeshellarg($srgatewayip) . " ";
598
				mwexec($cmd . "-iface " . escapeshellarg($srinterfacegw));
599
				if (isset($config['system']['route-debug'])) {
600
					$mt = microtime();
601
					log_error("ROUTING debug: $mt - $cmd -iface $srinterfacegw ");
602
				}
603
			}
604
		}
605
	}
606

    
607
	if ($dont_add_route == false) {
608
		if (!empty($interface) && $interface != $interfacegw) {
609
			;
610
		} else if (is_ipaddrv4($gatewayip)) {
611
			log_error("ROUTING: setting default route to $gatewayip");
612
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
613
		}
614

    
615
		if (!empty($interface) && $interface != $interfacegwv6) {
616
			;
617
		} else if (is_ipaddrv6($gatewayipv6)) {
618
			$ifscope = "";
619
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
620
				$ifscope = "%{$defaultifv6}";
621
			}
622
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
623
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
624
		}
625
	}
626

    
627
	system_staticroutes_configure($interface, false);
628

    
629
	return 0;
630
}
631

    
632
function system_staticroutes_configure($interface = "", $update_dns = false) {
633
	global $config, $g, $aliastable;
634

    
635
	$filterdns_list = array();
636

    
637
	$static_routes = get_staticroutes(false, true);
638
	if (count($static_routes)) {
639
		$gateways_arr = return_gateways_array(false, true);
640

    
641
		foreach ($static_routes as $rtent) {
642
			if (empty($gateways_arr[$rtent['gateway']])) {
643
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
644
				continue;
645
			}
646
			$gateway = $gateways_arr[$rtent['gateway']];
647
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
648
				continue;
649
			}
650

    
651
			$gatewayip = $gateway['gateway'];
652
			$interfacegw = $gateway['interface'];
653

    
654
			$blackhole = "";
655
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
656
				$blackhole = "-blackhole";
657
			}
658

    
659
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
660
				continue;
661
			}
662

    
663
			$dnscache = array();
664
			if ($update_dns === true) {
665
				if (is_subnet($rtent['network'])) {
666
					continue;
667
				}
668
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
669
				if (empty($dnscache)) {
670
					continue;
671
				}
672
			}
673

    
674
			if (is_subnet($rtent['network'])) {
675
				$ips = array($rtent['network']);
676
			} else {
677
				if (!isset($rtent['disabled'])) {
678
					$filterdns_list[] = $rtent['network'];
679
				}
680
				$ips = add_hostname_to_watch($rtent['network']);
681
			}
682

    
683
			foreach ($dnscache as $ip) {
684
				if (in_array($ip, $ips)) {
685
					continue;
686
				}
687
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
688
				if (isset($config['system']['route-debug'])) {
689
					$mt = microtime();
690
					log_error("ROUTING debug: $mt - route delete $ip ");
691
				}
692
			}
693

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

    
706
			foreach ($ips as $ip) {
707
				if (is_ipaddrv4($ip)) {
708
					$ip .= "/32";
709
				}
710
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
711

    
712
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
713

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

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

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

    
748
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
749
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
750
			} else {
751
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
752
			}
753
		} else {
754
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
755
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
756
		}
757
	}
758
	unset($filterdns_list);
759

    
760
	return 0;
761
}
762

    
763
function system_routing_enable() {
764
	global $config, $g;
765
	if (isset($config['system']['developerspew'])) {
766
		$mt = microtime();
767
		echo "system_routing_enable() being called $mt\n";
768
	}
769

    
770
	set_sysctl(array(
771
		"net.inet.ip.forwarding" => "1",
772
		"net.inet6.ip6.forwarding" => "1"
773
	));
774

    
775
	return;
776
}
777

    
778
function system_syslogd_fixup_server($server) {
779
	/* If it's an IPv6 IP alone, encase it in brackets */
780
	if (is_ipaddrv6($server)) {
781
		return "[$server]";
782
	} else {
783
		return $server;
784
	}
785
}
786

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

    
805
function system_syslogd_start() {
806
	global $config, $g;
807
	if (isset($config['system']['developerspew'])) {
808
		$mt = microtime();
809
		echo "system_syslogd_start() being called $mt\n";
810
	}
811

    
812
	mwexec("/etc/rc.d/hostid start");
813

    
814
	$syslogcfg = $config['syslog'];
815

    
816
	if (platform_booting()) {
817
		echo gettext("Starting syslog...");
818
	}
819

    
820
	if (is_process_running("fifolog_writer")) {
821
		mwexec('/bin/pkill fifolog_writer');
822
	}
823

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

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

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

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

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

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

    
880
		$syslogconf .= "!l2tps\n";
881
		if (!isset($syslogcfg['disablelocallogging'])) {
882
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
883
		}
884

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

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

    
901
		$syslogconf .= "!apinger\n";
902
		if (!isset($syslogcfg['disablelocallogging'])) {
903
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
904
		}
905
		if (isset($syslogcfg['apinger'])) {
906
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
907
		}
908

    
909
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
910
		if (!isset($syslogcfg['disablelocallogging'])) {
911
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
912
		}
913

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

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

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

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

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

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

    
982
		if (isset($syslogcfg['zmqserver'])) {
983
				$syslogconf .= <<<EOD
984
*.*								^{$syslogcfg['zmqserver']}
985

    
986
EOD;
987
		}
988
		/* write syslog.conf */
989
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
990
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
991
			unset($syslogconf);
992
			return 1;
993
		}
994
		unset($syslogconf);
995

    
996
		// Ensure that the log directory exists
997
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
998
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
999
		}
1000

    
1001
		$sourceip = "";
1002
		if (!empty($syslogcfg['sourceip'])) {
1003
			if ($syslogcfg['ipproto'] == "ipv6") {
1004
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
1005
				if (!is_ipaddr($ifaddr)) {
1006
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
1007
				}
1008
			} else {
1009
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1010
				if (!is_ipaddr($ifaddr)) {
1011
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1012
				}
1013
			}
1014
			if (is_ipaddr($ifaddr)) {
1015
				$sourceip = "-b {$ifaddr}";
1016
			}
1017
		}
1018

    
1019
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1020
	}
1021

    
1022
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1023
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1024
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1025
	}
1026

    
1027
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1028
		// if it still hasn't responded to the TERM, KILL it.
1029
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1030
		usleep(100000);
1031
	}
1032

    
1033

    
1034
	$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}");
1035

    
1036
	if (platform_booting()) {
1037
		echo gettext("done.") . "\n";
1038
	}
1039

    
1040
	return $retval;
1041
}
1042

    
1043
function system_webgui_create_certificate() {
1044
	global $config, $g;
1045

    
1046
	if (!is_array($config['ca'])) {
1047
		$config['ca'] = array();
1048
	}
1049
	$a_ca =& $config['ca'];
1050
	if (!is_array($config['cert'])) {
1051
		$config['cert'] = array();
1052
	}
1053
	$a_cert =& $config['cert'];
1054
	log_error("Creating SSL Certificate for this host");
1055

    
1056
	$cert = array();
1057
	$cert['refid'] = uniqid();
1058
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1059

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

    
1077
	$a_cert[] = $cert;
1078
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1079
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
1080
	return $cert;
1081
}
1082

    
1083
function system_webgui_start() {
1084
	global $config, $g;
1085

    
1086
	if (platform_booting()) {
1087
		echo gettext("Starting webConfigurator...");
1088
	}
1089

    
1090
	chdir($g['www_path']);
1091

    
1092
	/* defaults */
1093
	$portarg = "80";
1094
	$crt = "";
1095
	$key = "";
1096
	$ca = "";
1097

    
1098
	/* non-standard port? */
1099
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1100
		$portarg = "{$config['system']['webgui']['port']}";
1101
	}
1102

    
1103
	if ($config['system']['webgui']['protocol'] == "https") {
1104
		// Ensure that we have a webConfigurator CERT
1105
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1106
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1107
			$cert = system_webgui_create_certificate();
1108
		}
1109
		$crt = base64_decode($cert['crt']);
1110
		$key = base64_decode($cert['prv']);
1111

    
1112
		if (!$config['system']['webgui']['port']) {
1113
			$portarg = "443";
1114
		}
1115
		$ca = ca_chain($cert);
1116
	}
1117

    
1118
	/* generate lighttpd configuration */
1119
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
1120
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
1121
		"cert.pem", "ca.pem");
1122

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

    
1126
	sleep(1);
1127

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

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

    
1133
	if (platform_booting()) {
1134
		if ($res == 0) {
1135
			echo gettext("done.") . "\n";
1136
		} else {
1137
			echo gettext("failed!") . "\n";
1138
		}
1139
	}
1140

    
1141
	return $res;
1142
}
1143

    
1144
function system_generate_lighty_config($filename,
1145
	$cert,
1146
	$key,
1147
	$ca,
1148
	$pid_file,
1149
	$port = 80,
1150
	$document_root = "/usr/local/www/",
1151
	$cert_location = "cert.pem",
1152
	$ca_location = "ca.pem",
1153
	$captive_portal = false) {
1154

    
1155
	global $config, $g;
1156

    
1157
	if (!is_dir("{$g['tmp_path']}/lighttpdcompress")) {
1158
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1159
	}
1160

    
1161
	if (isset($config['system']['developerspew'])) {
1162
		$mt = microtime();
1163
		echo "system_generate_lighty_config() being called $mt\n";
1164
	}
1165

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

    
1170
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1171
		if (empty($maxprocperip)) {
1172
			$maxprocperip = 10;
1173
		}
1174
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
1175

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

    
1191
	if (empty($port)) {
1192
		$lighty_port = "80";
1193
	} else {
1194
		$lighty_port = $port;
1195
	}
1196

    
1197
	$memory = get_memory();
1198
	$realmem = $memory[1];
1199

    
1200
	// Determine web GUI process settings and take into account low memory systems
1201
	if ($realmem < 255) {
1202
		$max_procs = 1;
1203
	} else {
1204
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1205
	}
1206

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

    
1222
	} else {
1223
		if ($realmem < 78) {
1224
			$max_php_children = 0;
1225
		} else {
1226
			$max_php_children = 1;
1227
		}
1228
	}
1229

    
1230
	if (!isset($config['syslog']['nologlighttpd'])) {
1231
		$lighty_use_syslog = <<<EOD
1232
## where to send error-messages to
1233
server.errorlog-use-syslog="enable"
1234
EOD;
1235
	}
1236

    
1237

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

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

    
1272
EOD;
1273
	}
1274

    
1275

    
1276
	$lighty_config = <<<EOD
1277
#
1278
# lighttpd configuration file
1279
#
1280
# use a it as base for lighttpd 1.0.0 and above
1281
#
1282
############ Options you really have to take care of ####################
1283

    
1284
## FreeBSD!
1285
server.event-handler	= "freebsd-kqueue"
1286
server.network-backend 	= "writev"
1287
#server.use-ipv6 = "enable"
1288

    
1289
## modules to load
1290
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1291
	{$captiveportal}, "mod_fastcgi"
1292
)
1293

    
1294
server.max-keep-alive-requests = 15
1295
server.max-keep-alive-idle = 30
1296

    
1297
## a static document-root, for virtual-hosting take look at the
1298
## server.virtual-* options
1299
server.document-root        = "{$document_root}"
1300
{$captive_portal_rewrite}
1301

    
1302
# Maximum idle time with nothing being written (php downloading)
1303
server.max-write-idle = 999
1304

    
1305
{$lighty_use_syslog}
1306

    
1307
# files to check for if .../ is requested
1308
server.indexfiles           = ( "index.php", "index.html",
1309
                                "index.htm", "default.htm" )
1310

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

    
1365
# Use the "Content-Type" extended attribute to obtain mime type if possible
1366
#mimetypes.use-xattr        = "enable"
1367

    
1368
## deny access the file-extensions
1369
#
1370
# ~    is for backupfiles from vi, emacs, joe, ...
1371
# .inc is often used for code includes which should in general not be part
1372
#      of the document-root
1373
url.access-deny             = ( "~", ".inc" )
1374

    
1375

    
1376
######### Options that are good to be but not necessary to be changed #######
1377

    
1378
## disable server header
1379
server.tag = ""
1380

    
1381
## bind to port (default: 80)
1382

    
1383
EOD;
1384

    
1385
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1386
	$lighty_config .= "server.port  = {$lighty_port}\n";
1387
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1388
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1389
	if ($cert <> "" and $key <> "") {
1390
		$lighty_config .= "\n";
1391
		$lighty_config .= "## ssl configuration\n";
1392
		$lighty_config .= "ssl.engine = \"enable\"\n";
1393
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1394
		if ($ca <> "") {
1395
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1396
		}
1397
	}
1398
	$lighty_config .= " }\n";
1399

    
1400

    
1401
	$lighty_config .= <<<EOD
1402

    
1403
## error-handler for status 404
1404
#server.error-handler-404   = "/error-handler.html"
1405
#server.error-handler-404   = "/error-handler.php"
1406

    
1407
## to help the rc.scripts
1408
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1409

    
1410
## virtual directory listings
1411
server.dir-listing         = "disable"
1412

    
1413
## enable debugging
1414
debug.log-request-header   = "disable"
1415
debug.log-response-header  = "disable"
1416
debug.log-request-handling = "disable"
1417
debug.log-file-not-found   = "disable"
1418

    
1419
# gzip compression
1420
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1421
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1422

    
1423
{$server_upload_dirs}
1424

    
1425
{$server_max_request_size}
1426

    
1427
{$fastcgi_config}
1428

    
1429
{$cgi_config}
1430

    
1431
{$captive_portal_mod_evasive}
1432

    
1433
expire.url = (
1434
		"" => "access 50 hours",
1435
	)
1436

    
1437
EOD;
1438

    
1439
	$cert = str_replace("\r", "", $cert);
1440
	$key = str_replace("\r", "", $key);
1441
	$ca = str_replace("\r", "", $ca);
1442

    
1443
	$cert = str_replace("\n\n", "\n", $cert);
1444
	$key = str_replace("\n\n", "\n", $key);
1445
	$ca = str_replace("\n\n", "\n", $ca);
1446

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

    
1473
		// SSLv2/3 is deprecated, force use of TLS
1474
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1475
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1476

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

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

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

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

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

    
1514
	return 0;
1515

    
1516
}
1517

    
1518
function system_get_timezone_list() {
1519
	global $g;
1520

    
1521
	$file_list = array_merge(
1522
		glob("/usr/share/zoneinfo/[A-Z]*"),
1523
		glob("/usr/share/zoneinfo/*/*"),
1524
		glob("/usr/share/zoneinfo/*/*/*")
1525
	);
1526

    
1527
	if (empty($file_list)) {
1528
		$file_list[] = $g['default_timezone'];
1529
	} else {
1530
		/* Remove directories from list */
1531
		$file_list = array_filter($file_list, function($v) {
1532
			return !is_dir($v);
1533
		});
1534
	}
1535

    
1536
	/* Remove directory prefix */
1537
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1538

    
1539
	sort($file_list);
1540

    
1541
	return $file_list;
1542
}
1543

    
1544
function system_timezone_configure() {
1545
	global $config, $g;
1546
	if (isset($config['system']['developerspew'])) {
1547
		$mt = microtime();
1548
		echo "system_timezone_configure() being called $mt\n";
1549
	}
1550

    
1551
	$syscfg = $config['system'];
1552

    
1553
	if (platform_booting()) {
1554
		echo gettext("Setting timezone...");
1555
	}
1556

    
1557
	/* extract appropriate timezone file */
1558
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1559
	conf_mount_rw();
1560
	/* DO NOT remove \n otherwise tzsetup will fail */
1561
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1562
	mwexec("/usr/sbin/tzsetup -r");
1563
	conf_mount_ro();
1564

    
1565
	if (platform_booting()) {
1566
		echo gettext("done.") . "\n";
1567
	}
1568
}
1569

    
1570
function system_ntp_setup_gps($serialport) {
1571
	global $config, $g;
1572
	$gps_device = '/dev/gps0';
1573
	$serialport = '/dev/'.$serialport;
1574

    
1575
	if (!file_exists($serialport)) {
1576
		return false;
1577
	}
1578

    
1579
	conf_mount_rw();
1580
	// Create symlink that ntpd requires
1581
	unlink_if_exists($gps_device);
1582
	@symlink($serialport, $gps_device);
1583

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

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

    
1608
	/* Send the following to the GPS port to initialize the GPS */
1609
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1610
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1611
	} else {
1612
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1613
	}
1614

    
1615
	/* XXX: Why not file_put_contents to the device */
1616
	@file_put_contents('/tmp/gps.init', $gps_init);
1617
	mwexec("cat /tmp/gps.init > {$serialport}");
1618

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

    
1624
	conf_mount_ro();
1625

    
1626
	return true;
1627
}
1628

    
1629
function system_ntp_setup_pps($serialport) {
1630
	global $config, $g;
1631

    
1632
	$pps_device = '/dev/pps0';
1633
	$serialport = '/dev/'.$serialport;
1634

    
1635
	if (!file_exists($serialport)) {
1636
		return false;
1637
	}
1638

    
1639
	conf_mount_rw();
1640
	// Create symlink that ntpd requires
1641
	unlink_if_exists($pps_device);
1642
	@symlink($serialport, $pps_device);
1643

    
1644
	conf_mount_ro();
1645

    
1646
	return true;
1647
}
1648

    
1649

    
1650
function system_ntp_configure($start_ntpd=true) {
1651
	global $config, $g;
1652

    
1653
	$driftfile = "/var/db/ntpd.drift";
1654
	$statsdir = "/var/log/ntp";
1655
	$gps_device = '/dev/gps0';
1656

    
1657
	safe_mkdir($statsdir);
1658

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

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

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

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

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

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

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

    
1874
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1875
	$ntpcfg .= "\n";
1876
	if (!empty($config['ntpd']['leapsec'])) {
1877
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1878
		file_put_contents('/var/db/leap-seconds', $leapsec);
1879
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1880
	}
1881

    
1882

    
1883
	if (empty($config['ntpd']['interface'])) {
1884
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1885
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1886
		} else {
1887
			$interfaces = array();
1888
		}
1889
	} else {
1890
		$interfaces = explode(",", $config['ntpd']['interface']);
1891
	}
1892

    
1893
	if (is_array($interfaces) && count($interfaces)) {
1894
		$ntpcfg .= "interface ignore all\n";
1895
		foreach ($interfaces as $interface) {
1896
			if (strstr($interface, "_vip")) {
1897
				$interface = get_configured_carp_interface_list($interface);
1898
			}
1899
			if (!is_ipaddr($interface)) {
1900
				$interface = get_real_interface($interface);
1901
			}
1902
			if (!empty($interface)) {
1903
				$ntpcfg .= "interface listen {$interface}\n";
1904
			}
1905
		}
1906
	}
1907

    
1908
	/* open configuration for writing or bail */
1909
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1910
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1911
		return;
1912
	}
1913

    
1914
	/* At bootup we just want to write out the config. */
1915
	if (!$start_ntpd) {
1916
		return;
1917
	}
1918

    
1919
	/* if ntpd is running, kill it */
1920
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1921
		killbypid("{$g['varrun_path']}/ntpd.pid");
1922
	}
1923
	@unlink("{$g['varrun_path']}/ntpd.pid");
1924

    
1925
	/* if /var/empty does not exist, create it */
1926
	if (!is_dir("/var/empty")) {
1927
		mkdir("/var/empty", 0775, true);
1928
	}
1929

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

    
1933
	// Note that we are starting up
1934
	log_error("NTPD is starting up.");
1935
	return;
1936
}
1937

    
1938
function sync_system_time() {
1939
	global $config, $g;
1940

    
1941
	if (platform_booting()) {
1942
		echo gettext("Syncing system time before startup...");
1943
	}
1944

    
1945
	/* foreach through servers and write out to ntpd.conf */
1946
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1947
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1948
	}
1949

    
1950
	if (platform_booting()) {
1951
		echo gettext("done.") . "\n";
1952
	}
1953

    
1954
}
1955

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

    
1959
	system_reboot_cleanup();
1960

    
1961
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1962
}
1963

    
1964
function system_reboot() {
1965
	global $g;
1966

    
1967
	system_reboot_cleanup();
1968

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

    
1972
function system_reboot_sync() {
1973
	global $g;
1974

    
1975
	system_reboot_cleanup();
1976

    
1977
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1978
}
1979

    
1980
function system_reboot_cleanup() {
1981
	global $config, $cpzone;
1982

    
1983
	mwexec("/usr/local/bin/beep.sh stop");
1984
	require_once("captiveportal.inc");
1985
	if (is_array($config['captiveportal'])) {
1986
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1987
			captiveportal_radius_stop_all();
1988
			captiveportal_send_server_accounting(true);
1989
		}
1990
	}
1991
	require_once("voucher.inc");
1992
	voucher_save_db_to_config();
1993
	require_once("pkg-utils.inc");
1994
	stop_packages();
1995
}
1996

    
1997
function system_do_shell_commands($early = 0) {
1998
	global $config, $g;
1999
	if (isset($config['system']['developerspew'])) {
2000
		$mt = microtime();
2001
		echo "system_do_shell_commands() being called $mt\n";
2002
	}
2003

    
2004
	if ($early) {
2005
		$cmdn = "earlyshellcmd";
2006
	} else {
2007
		$cmdn = "shellcmd";
2008
	}
2009

    
2010
	if (is_array($config['system'][$cmdn])) {
2011

    
2012
		/* *cmd is an array, loop through */
2013
		foreach ($config['system'][$cmdn] as $cmd) {
2014
			exec($cmd);
2015
		}
2016

    
2017
	} elseif ($config['system'][$cmdn] <> "") {
2018

    
2019
		/* execute single item */
2020
		exec($config['system'][$cmdn]);
2021

    
2022
	}
2023
}
2024

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

    
2032
	if (isset($config['system']['disableconsolemenu'])) {
2033
		touch("{$g['varetc_path']}/disableconsole");
2034
	} else {
2035
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
2036
	}
2037
}
2038

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

    
2046
	$dmesg = "";
2047
	$_gb = exec("/sbin/dmesg", $dmesg);
2048

    
2049
	/* find last copyright line (output from previous boots may be present) */
2050
	$lastcpline = 0;
2051

    
2052
	for ($i = 0; $i < count($dmesg); $i++) {
2053
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
2054
			$lastcpline = $i;
2055
		}
2056
	}
2057

    
2058
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
2059
	if (!$fd) {
2060
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
2061
		return 1;
2062
	}
2063

    
2064
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
2065
		fwrite($fd, $dmesg[$i] . "\n");
2066
	}
2067

    
2068
	fclose($fd);
2069
	unset($dmesg);
2070

    
2071
	return 0;
2072
}
2073

    
2074
function system_set_harddisk_standby() {
2075
	global $g, $config;
2076

    
2077
	if (isset($config['system']['developerspew'])) {
2078
		$mt = microtime();
2079
		echo "system_set_harddisk_standby() being called $mt\n";
2080
	}
2081

    
2082
	if (isset($config['system']['harddiskstandby'])) {
2083
		if (platform_booting()) {
2084
			echo gettext('Setting hard disk standby... ');
2085
		}
2086

    
2087
		$standby = $config['system']['harddiskstandby'];
2088
		// Check for a numeric value
2089
		if (is_numeric($standby)) {
2090
			// Get only suitable candidates for standby; using get_smart_drive_list()
2091
			// from utils.inc to get the list of drives.
2092
			$harddisks = get_smart_drive_list();
2093

    
2094
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
2095
			// just in case of some weird pfSense platform installs.
2096
			if (count($harddisks) > 0) {
2097
				// Iterate disks and run the camcontrol command for each
2098
				foreach ($harddisks as $harddisk) {
2099
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
2100
				}
2101
				if (platform_booting()) {
2102
					echo gettext("done.") . "\n";
2103
				}
2104
			} else if (platform_booting()) {
2105
				echo gettext("failed!") . "\n";
2106
			}
2107
		} else if (platform_booting()) {
2108
			echo gettext("failed!") . "\n";
2109
		}
2110
	}
2111
}
2112

    
2113
function system_setup_sysctl() {
2114
	global $config;
2115
	if (isset($config['system']['developerspew'])) {
2116
		$mt = microtime();
2117
		echo "system_setup_sysctl() being called $mt\n";
2118
	}
2119

    
2120
	activate_sysctls();
2121

    
2122
	if (isset($config['system']['sharednet'])) {
2123
		system_disable_arp_wrong_if();
2124
	}
2125
}
2126

    
2127
function system_disable_arp_wrong_if() {
2128
	global $config;
2129
	if (isset($config['system']['developerspew'])) {
2130
		$mt = microtime();
2131
		echo "system_disable_arp_wrong_if() being called $mt\n";
2132
	}
2133
	set_sysctl(array(
2134
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2135
		"net.link.ether.inet.log_arp_movements" => "0"
2136
	));
2137
}
2138

    
2139
function system_enable_arp_wrong_if() {
2140
	global $config;
2141
	if (isset($config['system']['developerspew'])) {
2142
		$mt = microtime();
2143
		echo "system_enable_arp_wrong_if() being called $mt\n";
2144
	}
2145
	set_sysctl(array(
2146
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2147
		"net.link.ether.inet.log_arp_movements" => "1"
2148
	));
2149
}
2150

    
2151
function enable_watchdog() {
2152
	global $config;
2153
	return;
2154
	$install_watchdog = false;
2155
	$supported_watchdogs = array("Geode");
2156
	$file = file_get_contents("/var/log/dmesg.boot");
2157
	foreach ($supported_watchdogs as $sd) {
2158
		if (stristr($file, "Geode")) {
2159
			$install_watchdog = true;
2160
		}
2161
	}
2162
	if ($install_watchdog == true) {
2163
		if (is_process_running("watchdogd")) {
2164
			mwexec("/usr/bin/killall watchdogd", true);
2165
		}
2166
		exec("/usr/sbin/watchdogd");
2167
	}
2168
}
2169

    
2170
function system_check_reset_button() {
2171
	global $g;
2172

    
2173
	$specplatform = system_identify_specific_platform();
2174

    
2175
	switch ($specplatform['name']) {
2176
		case 'alix':
2177
		case 'wrap':
2178
		case 'FW7541':
2179
		case 'APU':
2180
		case 'RCC-VE':
2181
		case 'RCC-DFF':
2182
			break;
2183
		default:
2184
			return 0;
2185
	}
2186

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

    
2189
	if ($retval == 99) {
2190
		/* user has pressed reset button for 2 seconds -
2191
		   reset to factory defaults */
2192
		echo <<<EOD
2193

    
2194
***********************************************************************
2195
* Reset button pressed - resetting configuration to factory defaults. *
2196
* The system will reboot after this completes.                        *
2197
***********************************************************************
2198

    
2199

    
2200
EOD;
2201

    
2202
		reset_factory_defaults();
2203
		system_reboot_sync();
2204
		exit(0);
2205
	}
2206

    
2207
	return 0;
2208
}
2209

    
2210
/* attempt to identify the specific platform (for embedded systems)
2211
   Returns an array with two elements:
2212
	name => platform string (e.g. 'wrap', 'alix' etc.)
2213
	descr => human-readable description (e.g. "PC Engines WRAP")
2214
*/
2215
function system_identify_specific_platform() {
2216
	global $g;
2217

    
2218
	if ($g['platform'] == 'generic-pc') {
2219
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2220
	}
2221

    
2222
	if ($g['platform'] == 'generic-pc-cdrom') {
2223
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2224
	}
2225

    
2226
	/* Try to guess from smbios strings */
2227
	unset($output);
2228
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2229
	switch ($output[0]) {
2230
		case 'FW7541':
2231
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2232
			break;
2233
		case 'APU':
2234
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2235
			break;
2236
		case 'RCC-VE':
2237
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2238
			break;
2239
		case 'DFFv2':
2240
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2241
			break;
2242
		case 'SYS-5018A-FTN4':
2243
		case 'A1SAi':
2244
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2245
			break;
2246
		case 'SYS-5018D-FN4T':
2247
			return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
2248
			break;
2249
	}
2250

    
2251
	/* the rest of the code only deals with 'embedded' platforms */
2252
	if ($g['platform'] != 'nanobsd') {
2253
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2254
	}
2255

    
2256
	$dmesg = get_single_sysctl('hw.model');
2257

    
2258
	if (strpos($dmesg, "PC Engines WRAP") !== false) {
2259
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2260
	}
2261

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

    
2266
	if (preg_match("/Soekris net45../", $dmesg, $matches)) {
2267
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2268
	}
2269

    
2270
	if (preg_match("/Soekris net48../", $dmesg, $matches)) {
2271
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2272
	}
2273

    
2274
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2275
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2276
	}
2277

    
2278
	unset($dmesg);
2279

    
2280
	$dmesg_boot = system_get_dmesg_boot();
2281
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2282
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2283
	}
2284
	unset($dmesg_boot);
2285

    
2286
	/* unknown embedded platform */
2287
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2288
}
2289

    
2290
function system_get_dmesg_boot() {
2291
	global $g;
2292

    
2293
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2294
}
2295

    
2296
?>
(52-52/65)