Project

General

Profile

Download (39.9 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 f5da67d0 Bill Marquette
/****h* pfSense/config
3
 * NAME
4
 *   config.inc - Functions to manipulate config.xml
5
 * DESCRIPTION
6
 *   This include contains various config.xml specific functions.
7
 * HISTORY
8
 * $Id$
9
 ******
10
11 5b237745 Scott Ullrich
	config.inc
12 cfc707f7 Scott Ullrich
	Copyright (C) 2004 Scott Ullrich
13
	All rights reserved.
14 5b237745 Scott Ullrich
15 cfc707f7 Scott Ullrich
	originally part of m0n0wall (http://m0n0.ch/wall)
16 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
17
	All rights reserved.
18
19
	Redistribution and use in source and binary forms, with or without
20
	modification, are permitted provided that the following conditions are met:
21
22
	1. Redistributions of source code must retain the above copyright notice,
23
	   this list of conditions and the following disclaimer.
24
25
	2. Redistributions in binary form must reproduce the above copyright
26
	   notice, this list of conditions and the following disclaimer in the
27
	   documentation and/or other materials provided with the distribution.
28
29
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
	POSSIBILITY OF SUCH DAMAGE.
39
*/
40
41 96447b25 Scott Ullrich
/* do not load this file twice. */
42
if($config_inc_loaded == true)
43
	return;
44
else
45
	$config_inc_loaded = true;
46
47 5b237745 Scott Ullrich
/* include globals/utility/XML parser files */
48
require_once("globals.inc");
49
require_once("util.inc");
50 5957111e Scott Ullrich
require_once("pfsense-utils.inc");
51 5b237745 Scott Ullrich
require_once("xmlparse.inc");
52
53
/* read platform */
54
if (file_exists("{$g['etc_path']}/platform")) {
55
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
56
} else {
57
	$g['platform'] = "unknown";
58
}
59
60 727a2b91 Scott Ullrich
/* if /debugging exists, lets set $debugging
61
   so we can output more information */
62 1324a93a Scott Ullrich
if(file_exists("/debugging")) {
63 727a2b91 Scott Ullrich
	$debugging = true;
64 1324a93a Scott Ullrich
	$g['debug'] = true;
65
}
66 727a2b91 Scott Ullrich
67 49ed889c Scott Ullrich
if(file_exists("/cf/conf/config.xml")) {
68
	$config_contents = file_get_contents("/cf/conf/config.xml");
69
	if(stristr($config_contents, "m0n0wall") == true) {
70
		/* user has just upgraded to m0n0wall, replace root xml tags */
71
		echo "Upgrading m0n0wall configuration to pfSense... ";
72 d9413241 Scott Ullrich
		$config_contents = str_replace("m0n0wall","pfsense", $config_contents);
73 5af3e206 Scott Ullrich
		if (!config_validate($config_contents))
74
			log_error("ERROR!  Could not convert m0n0wall -> pfsense in config.xml");	
75 49ed889c Scott Ullrich
		$fd = fopen("/cf/conf/config.xml", "w");
76
		fwrite($fd, $config_contents);
77
		fclose($fd);
78
		echo "done.";
79
	}
80 e9208daf Scott Ullrich
}
81 727a2b91 Scott Ullrich
82 6e8c1d1c Scott Ullrich
/* if our config file exists bail out, we're already set. */
83
if ($g['booting'] and !file_exists($g['cf_conf_path'] . "/config.xml")  ) {
84 5b237745 Scott Ullrich
	/* find the device where config.xml resides and write out an fstab */
85
	unset($cfgdevice);
86
87
	/* check if there's already an fstab (NFS booting?) */
88
	if (!file_exists("{$g['etc_path']}/fstab")) {
89
90
		if (strstr($g['platform'], "cdrom")) {
91
			/* config is on floppy disk for CD-ROM version */
92
			$cfgdevice = $cfgpartition = "fd0";
93 e76de94e Scott Ullrich
			$dmesg = `dmesg -a`;
94 da9de371 Scott Ullrich
			if(ereg("da0", $dmesg) == true) {
95 e76de94e Scott Ullrich
				$cfgdevice = $cfgpartition = "da0" ;
96 da9de371 Scott Ullrich
				if (mwexec("/sbin/mount -r /dev/{$cfgdevice} /cf")) {
97 e76de94e Scott Ullrich
					/* could not mount, fallback to floppy */
98
					$cfgdevice = $cfgpartition = "fd0";
99
				}
100
			}
101 5b237745 Scott Ullrich
			$cfgfstype = "msdos";
102 c3cbc094 Scott Ullrich
			echo "CDROM build\n";
103
			echo "   CFG: {$cfgpartition}\n";
104
			echo "  TYPE: {$cfgfstype}\n";
105 5b237745 Scott Ullrich
		} else {
106
			/* probe kernel known disks until we find one with config.xml */
107
			$disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
108
			foreach ($disks as $mountdisk) {
109
				/* skip mfs mounted filesystems */
110
				if (strstr($mountdisk, "md"))
111
					continue;
112
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
113
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
114
						/* found it */
115
						$cfgdevice = $mountdisk;
116
						$cfgpartition = $cfgdevice . "a";
117
						$cfgfstype = "ufs";
118
						echo "Found configuration on $cfgdevice.\n";
119
					}
120
121
					mwexec("/sbin/umount -f {$g['cf_path']}");
122
123 655a80eb Scott Ullrich
					if ($cfgdevice)
124
						break;
125
				}
126
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}d {$g['cf_path']}") == 0) {
127
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
128
						/* found it */
129
						$cfgdevice = $mountdisk;
130 4de945fa Scott Ullrich
						$cfgpartition = $cfgdevice . "d";
131 655a80eb Scott Ullrich
						$cfgfstype = "ufs";
132
						echo "Found configuration on $cfgdevice.\n";
133
					}
134
135
					mwexec("/sbin/umount -f {$g['cf_path']}");
136
137 5b237745 Scott Ullrich
					if ($cfgdevice)
138
						break;
139
				}
140
			}
141
		}
142
143
		if (!$cfgdevice) {
144
			/* no device found, print an error and die */
145
			echo <<<EOD
146
147
148
*******************************************************************************
149
* FATAL ERROR                                                                 *
150
* The device that contains the configuration file (config.xml) could not be   *
151 ee11cc6e Scott Ullrich
* found. pfSense cannot continue booting.                                     *
152 5b237745 Scott Ullrich
*******************************************************************************
153
154
155
EOD;
156
157
			mwexec("/sbin/halt");
158
			exit;
159
		}
160
161
		/* write device name to a file for rc.firmware */
162
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
163
		fwrite($fd, $cfgdevice . "\n");
164
		fclose($fd);
165
166
		/* write out an fstab */
167
		$fd = fopen("{$g['etc_path']}/fstab", "w");
168
169
		$fstab = "/dev/{$cfgpartition} {$g['cf_path']} {$cfgfstype} ro 1 1\n";
170
		$fstab .= "proc /proc procfs rw 0 0\n";
171
172
		fwrite($fd, $fstab);
173
		fclose($fd);
174
	}
175
176
	/* mount all filesystems */
177
	mwexec("/sbin/mount -a");
178
}
179
180 5cabfeb3 Scott Ullrich
$config = parse_config();
181
182 f5da67d0 Bill Marquette
/****f* config/parse_config
183
 * NAME
184
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
185
 * INPUTS
186
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
187
 * RESULT
188
 *   $config      - array containing all configuration variables
189
 ******/
190 781beaaa Colin Smith
function parse_config($parse = false) {
191 baa7645c Colin Smith
	global $g;
192 d9e8c3bc Bill Marquette
193
	config_lock();
194 781beaaa Colin Smith
	if(!$parse) {
195
		if(file_exists($g['tmp_path'] . '/config.cache')) {
196
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
197 baa7645c Colin Smith
			if(is_null($config)) {
198 d9e8c3bc Bill Marquette
				config_unlock();
199 baa7645c Colin Smith
				parse_config(true);
200
			}
201 781beaaa Colin Smith
		} else {
202 d9e8c3bc Bill Marquette
			config_unlock();
203 baa7645c Colin Smith
			$config = parse_config(true);
204 781beaaa Colin Smith
		}
205 ffd1b445 Scott Ullrich
	} else {
206 781beaaa Colin Smith
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
207 baa7645c Colin Smith
		generate_config_cache($config);
208 781beaaa Colin Smith
	}
209 1886ba69 Scott Ullrich
	
210 918a884d Bill Marquette
	alias_make_table($config);
211 d9e8c3bc Bill Marquette
	config_unlock();
212 aa9fd9e6 Scott Ullrich
213
	/*    override some global configuration parms if they exist
214
	 *    instead of hard coding these checks into the codebase
215
         */	
216
	if($config['pptp']['n_pptp_units'])
217
		$g['n_pptp_units'] = $config['pptp']['n_pptp_units'];
218
	if($config['pptp']['pptp_subnet'])
219
		$g['pptp_subnet'] = $config['pptp']['pptp_subnet'];
220
    
221
	if($config['pppoe']['n_pppoe_units'])
222
		$g['n_pppoe_units'] = $config['pppoe']['n_pppoe_units'];
223
	if($config['pppoe']['pppoe_subnet'])
224
		$g['pppoe_subnet'] = $config['pppoe']['pppoe_subnet'];
225
226 baa7645c Colin Smith
	return $config;
227 41508358 Scott Ullrich
}
228 5b237745 Scott Ullrich
229 840c97dc Colin Smith
/****f* config/generate_config_cache
230
 * NAME
231
 *   generate_config_cache - Write serialized configuration to cache.
232
 * INPUTS
233
 *   $config	- array containing current firewall configuration
234
 * RESULT
235
 *   boolean	- true on completion
236
 ******/
237 baa7645c Colin Smith
function generate_config_cache($config) {
238
	global $g;
239 842bf9f1 Scott Ullrich
	conf_mount_rw();
240 41508358 Scott Ullrich
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
241
	fwrite($configcache, serialize($config));
242
	fclose($configcache);
243 842bf9f1 Scott Ullrich
	conf_mount_ro();
244 41508358 Scott Ullrich
	return true;
245
}
246
247 840c97dc Colin Smith
/****f* config/parse_config_bootup
248
 * NAME
249
 *   parse_config_bootup - Bootup-specific configuration checks.
250
 * RESULT
251
 *   null
252
 ******/
253 41508358 Scott Ullrich
function parse_config_bootup() {
254 a8a5bdfc Scott Ullrich
	global $config, $g, $noparseconfig;
255 41508358 Scott Ullrich
	if (!$noparseconfig) {
256 5b237745 Scott Ullrich
		if (!file_exists("{$g['conf_path']}/config.xml")) {
257 41508358 Scott Ullrich
			config_lock();
258 5b237745 Scott Ullrich
			if ($g['booting']) {
259
				if (strstr($g['platform'], "cdrom")) {
260
					/* try copying the default config. to the floppy */
261 c3cbc094 Scott Ullrich
					echo "Resetting factory defaults...\n";
262 5b237745 Scott Ullrich
					reset_factory_defaults();
263 41508358 Scott Ullrich
	
264 5b237745 Scott Ullrich
					echo "No XML configuration file found - using factory defaults.\n";
265
					echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
266
					echo "file is inserted. If it isn't, your configuration changes will be lost\n";
267
					echo "on reboot.\n";
268
				} else {
269 6e8c1d1c Scott Ullrich
					echo "XML configuration file not found.  pfSense cannot continue booting.\n";
270 5b237745 Scott Ullrich
					mwexec("/sbin/halt");
271
					exit;
272
				}
273
			} else {
274
				config_unlock();
275
				exit(0);
276
			}
277
		}
278 41508358 Scott Ullrich
	}
279 5b237745 Scott Ullrich
280 5c6d0f65 Colin Smith
	parse_config(true);
281
	
282 41508358 Scott Ullrich
	if ((float)$config['version'] > (float)$g['latest_config']) {
283 5c6d0f65 Colin Smith
		echo <<<EOD
284 5b237745 Scott Ullrich
285
286
*******************************************************************************
287
* WARNING!                                                                    *
288 ee11cc6e Scott Ullrich
* The current configuration has been created with a newer version of pfSense  *
289 5b237745 Scott Ullrich
* than this one! This can lead to serious misbehavior and even security       *
290 ee11cc6e Scott Ullrich
* holes! You are urged to either upgrade to a newer version of pfSense or     *
291 5b237745 Scott Ullrich
* revert to the default configuration immediately!                            *
292
*******************************************************************************
293
294
295
EOD;
296
		}
297
298
	/* make alias table (for faster lookups) */
299 918a884d Bill Marquette
	alias_make_table($config);
300 d9e8c3bc Bill Marquette
	config_unlock();
301 5b237745 Scott Ullrich
}
302
303 840c97dc Colin Smith
/****f* config/conf_mount_rw
304
 * NAME
305
 *   conf_mount_rw - Mount filesystems read/write.
306
 * RESULT
307
 *   null
308
 ******/
309 5b237745 Scott Ullrich
/* mount flash card read/write */
310
function conf_mount_rw() {
311
	global $g;
312
313 875e24be Scott Ullrich
	/* do not mount on cdrom platform */
314 6f4f5eb3 Scott Ullrich
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
315 875e24be Scott Ullrich
		return;
316
317 6f4f5eb3 Scott Ullrich
	$status = mwexec("/sbin/umount -f {$g['cf_path']}");
318 1324a93a Scott Ullrich
	$status = mwexec("/sbin/mount -w {$g['cf_path']}");
319 4fde4ce4 Colin Smith
	if($status <> 0) {
320
		mwexec("/sbin/fsck -y {$g['cf_path']}");
321 1324a93a Scott Ullrich
		$status = mwexec("/sbin/mount -w {$g['cf_path']}");
322 18859f3b Scott Ullrich
	}
323 14249fda Scott Ullrich
324 578d4f38 Scott Ullrich
	/*    if the platform is soekris or wrap or pfSense, lets mount the
325
	 *    compact flash cards root.
326
         */
327 3e52930a Scott Ullrich
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx"
328
	   or $g['platform'] == "embedded") {
329 1273abab Scott Ullrich
		$status = mwexec("/sbin/mount -w /");
330 1ef6e981 Scott Ullrich
		/* we could not mount this correctly.  kick off fsck */
331 4fde4ce4 Colin Smith
		if($status <> 0) {
332 1ef6e981 Scott Ullrich
			log_error("File system is dirty.  Launching FSCK for /");
333
			mwexec("/sbin/fsck -y");
334 1273abab Scott Ullrich
			$status = mwexec("/sbin/mount -w /");
335 1ef6e981 Scott Ullrich
		}
336 c8b8a2b7 Scott Ullrich
	}
337 01ee30ef Scott Ullrich
	
338
	usleep(100);
339
	
340 5b237745 Scott Ullrich
}
341
342 840c97dc Colin Smith
/****f* config/conf_mount_ro
343
 * NAME         
344
 *   conf_mount_ro - Mount filesystems readonly.
345
 * RESULT
346
 *   null        
347
 ******/
348 5b237745 Scott Ullrich
function conf_mount_ro() {
349 669e1adb Bill Marquette
	global $g;
350 f699da52 Scott Ullrich
351 81e3bbc7 Scott Ullrich
	if($g['booting'] == true)
352
		return;
353
	
354
	/* do not umount if generating ssh keys */
355
	if(file_exists("/tmp/keys_generating"))
356
		return;
357 855ec374 Scott Ullrich
	
358 1dc67b04 Scott Ullrich
	/* do not umount on cdrom or pfSense platforms */
359
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
360 ac4878f9 Scott Ullrich
		return;
361 5b237745 Scott Ullrich
362 312710db Scott Ullrich
	/* sync data, then force a umount the remount of /cf */
363
	mwexec("/bin/sync");
364 1dc67b04 Scott Ullrich
	mwexec("/bin/sync");
365 312710db Scott Ullrich
	mwexec("/sbin/umount -f {$g['cf_path']}");
366 1273abab Scott Ullrich
	mwexec("/sbin/mount -r {$g['cf_path']}");
367 1dc67b04 Scott Ullrich
	mwexec("/bin/sync");
368
	mwexec("/bin/sync");
369
	mwexec("/sbin/mount -r /");
370 01ee30ef Scott Ullrich
	
371
	usleep(100);
372
373 5b237745 Scott Ullrich
}
374
375 840c97dc Colin Smith
/****f* config/convert_config
376
 * NAME         
377
 *   convert_config - Attempt to update config.xml.
378
 * DESCRIPTION
379
 *   convert_config() reads the current global configuration
380
 *   and attempts to convert it to conform to the latest
381
 *   config.xml version. This allows major formatting changes
382
 *   to be made with a minimum of breakage.
383
 * RESULT
384
 *   null        
385
 ******/
386 5b237745 Scott Ullrich
/* convert configuration, if necessary */
387
function convert_config() {
388 669e1adb Bill Marquette
	global $config, $g;
389 5b237745 Scott Ullrich
390
	if ($config['version'] == $g['latest_config'])
391
		return;		/* already at latest version */
392
393 d05dff82 Bill Marquette
	// Save off config version
394
	$prev_version = $config['version'];
395
396 5b237745 Scott Ullrich
	/* convert 1.0 -> 1.1 */
397
	if ($config['version'] == "1.0") {
398
		$opti = 1;
399
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
400
401
		/* convert DMZ to optional, if necessary */
402
		if (isset($config['interfaces']['dmz'])) {
403
404
			$dmzcfg = &$config['interfaces']['dmz'];
405
406
			if ($dmzcfg['if']) {
407
				$config['interfaces']['opt' . $opti] = array();
408
				$optcfg = &$config['interfaces']['opt' . $opti];
409
410
				$optcfg['enable'] = $dmzcfg['enable'];
411
				$optcfg['descr'] = "DMZ";
412
				$optcfg['if'] = $dmzcfg['if'];
413
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
414
				$optcfg['subnet'] = $dmzcfg['subnet'];
415
416
				$ifmap['dmz'] = "opt" . $opti;
417
				$opti++;
418
			}
419
420
			unset($config['interfaces']['dmz']);
421
		}
422
423
		/* convert WLAN1/2 to optional, if necessary */
424
		for ($i = 1; isset($config['interfaces']['wlan' . $i]); $i++) {
425
426
			if (!$config['interfaces']['wlan' . $i]['if']) {
427
				unset($config['interfaces']['wlan' . $i]);
428
				continue;
429
			}
430
431
			$wlancfg = &$config['interfaces']['wlan' . $i];
432
			$config['interfaces']['opt' . $opti] = array();
433
			$optcfg = &$config['interfaces']['opt' . $opti];
434
435
			$optcfg['enable'] = $wlancfg['enable'];
436
			$optcfg['descr'] = "WLAN" . $i;
437
			$optcfg['if'] = $wlancfg['if'];
438
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
439
			$optcfg['subnet'] = $wlancfg['subnet'];
440
			$optcfg['bridge'] = $wlancfg['bridge'];
441
442
			$optcfg['wireless'] = array();
443
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
444
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
445
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
446
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
447
448
			$ifmap['wlan' . $i] = "opt" . $opti;
449
450
			unset($config['interfaces']['wlan' . $i]);
451
			$opti++;
452
		}
453
454
		/* convert filter rules */
455
		$n = count($config['filter']['rule']);
456
		for ($i = 0; $i < $n; $i++) {
457
458
			$fr = &$config['filter']['rule'][$i];
459
460
			/* remap interface */
461
			if (array_key_exists($fr['interface'], $ifmap))
462
				$fr['interface'] = $ifmap[$fr['interface']];
463
			else {
464
				/* remove the rule */
465
				echo "\nWarning: filter rule removed " .
466
					"(interface '{$fr['interface']}' does not exist anymore).";
467
				unset($config['filter']['rule'][$i]);
468
				continue;
469
			}
470
471
			/* remap source network */
472
			if (isset($fr['source']['network'])) {
473
				if (array_key_exists($fr['source']['network'], $ifmap))
474
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
475
				else {
476
					/* remove the rule */
477
					echo "\nWarning: filter rule removed " .
478
						"(source network '{$fr['source']['network']}' does not exist anymore).";
479
					unset($config['filter']['rule'][$i]);
480
					continue;
481
				}
482
			}
483
484
			/* remap destination network */
485
			if (isset($fr['destination']['network'])) {
486
				if (array_key_exists($fr['destination']['network'], $ifmap))
487
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
488
				else {
489
					/* remove the rule */
490
					echo "\nWarning: filter rule removed " .
491
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
492
					unset($config['filter']['rule'][$i]);
493
					continue;
494
				}
495
			}
496
		}
497
498
		/* convert shaper rules */
499
		$n = count($config['pfqueueing']['rule']);
500
		if (is_array($config['pfqueueing']['rule']))
501
			for ($i = 0; $i < $n; $i++) {
502
503
			$fr = &$config['pfqueueing']['rule'][$i];
504
505
			/* remap interface */
506
			if (array_key_exists($fr['interface'], $ifmap))
507
				$fr['interface'] = $ifmap[$fr['interface']];
508
			else {
509
				/* remove the rule */
510
				echo "\nWarning: traffic shaper rule removed " .
511
					"(interface '{$fr['interface']}' does not exist anymore).";
512
				unset($config['pfqueueing']['rule'][$i]);
513
				continue;
514
			}
515
516
			/* remap source network */
517
			if (isset($fr['source']['network'])) {
518
				if (array_key_exists($fr['source']['network'], $ifmap))
519
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
520
				else {
521
					/* remove the rule */
522
					echo "\nWarning: traffic shaper rule removed " .
523
						"(source network '{$fr['source']['network']}' does not exist anymore).";
524
					unset($config['pfqueueing']['rule'][$i]);
525
					continue;
526
				}
527
			}
528
529
			/* remap destination network */
530
			if (isset($fr['destination']['network'])) {
531
				if (array_key_exists($fr['destination']['network'], $ifmap))
532
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
533
				else {
534
					/* remove the rule */
535
					echo "\nWarning: traffic shaper rule removed " .
536
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
537
					unset($config['pfqueueing']['rule'][$i]);
538
					continue;
539
				}
540
			}
541
		}
542
543
		$config['version'] = "1.1";
544
	}
545
546
	/* convert 1.1 -> 1.2 */
547
	if ($config['version'] == "1.1") {
548
		/* move LAN DHCP server config */
549
		$tmp = $config['dhcpd'];
550
		$config['dhcpd'] = array();
551
		$config['dhcpd']['lan'] = $tmp;
552
553
		/* encrypt password */
554
		$config['system']['password'] = crypt($config['system']['password']);
555
556
		$config['version'] = "1.2";
557
	}
558
559
	/* convert 1.2 -> 1.3 */
560
	if ($config['version'] == "1.2") {
561
		/* convert advanced outbound NAT config */
562
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
563
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
564
			$src = $curent['source'];
565
			$curent['source'] = array();
566
			$curent['source']['network'] = $src;
567
			$curent['destination'] = array();
568
			$curent['destination']['any'] = true;
569
		}
570
571
		/* add an explicit type="pass" to all filter rules to make things consistent */
572
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
573
			$config['filter']['rule'][$i]['type'] = "pass";
574
		}
575
576
		$config['version'] = "1.3";
577
	}
578
579
	/* convert 1.3 -> 1.4 */
580
	if ($config['version'] == "1.3") {
581
		/* convert shaper rules (make pipes) */
582
		if (is_array($config['pfqueueing']['rule'])) {
583
			$config['pfqueueing']['pipe'] = array();
584
585
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
586
				$curent = &$config['pfqueueing']['rule'][$i];
587
588
				/* make new pipe and associate with this rule */
589
				$newpipe = array();
590
				$newpipe['descr'] = $curent['descr'];
591
				$newpipe['bandwidth'] = $curent['bandwidth'];
592
				$newpipe['delay'] = $curent['delay'];
593
				$newpipe['mask'] = $curent['mask'];
594
				$config['pfqueueing']['pipe'][$i] = $newpipe;
595
596
				$curent['targetpipe'] = $i;
597
598
				unset($curent['bandwidth']);
599
				unset($curent['delay']);
600
				unset($curent['mask']);
601
			}
602
		}
603
604
		$config['version'] = "1.4";
605
	}
606
607 88f66e13 Bill Marquette
	/* Convert 1.4 -> 1.5 */
608
	if ($config['version'] == "1.4") {
609
610
		/* Default route moved */
611
		if (isset($config['interfaces']['wan']['gateway']))
612
			if ($config['interfaces']['wan']['gateway'] <> "")
613 588a183b Scott Ullrich
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
614 88f66e13 Bill Marquette
		unset($config['interfaces']['wan']['gateway']);
615
616
                /* Queues are no longer interface specific */
617
                if (isset($config['interfaces']['lan']['schedulertype']))
618
                        unset($config['interfaces']['lan']['schedulertype']);
619
                if (isset($config['interfaces']['wan']['schedulertype']))
620
                        unset($config['interfaces']['wan']['schedulertype']);
621
622
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
623
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
624
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
625
                }
626
627
		$config['version'] = "1.5";
628
	}
629
630 45cb953d Colin Smith
	/* Convert 1.5 -> 1.6 */
631 208c4390 Colin Smith
	if ($config['version'] == "1.5") {
632
		/* Alternate firmware URL moved */
633
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
634
			$config['system']['alt_firmware_url'] = array();
635
			$config['system']['alt_firmware_url']['enabled'] = "";
636
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
637
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
638
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
639
		} else {
640
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
641
		}
642 45cb953d Colin Smith
643 208c4390 Colin Smith
		$config['version'] = "1.6";
644
	}
645 7756e2b7 Scott Ullrich
	
646
	/* Convert 1.6 -> 1.7 */
647
	if ($config['version'] == "1.6") {
648
		/* wipe previous shaper configuration */
649
		unset($config['shaper']['queue']);
650
		unset($config['shaper']['rule']);
651
		unset($config['interfaces']['wan']['bandwidth']);
652
		unset($config['interfaces']['wan']['bandwidthtype']);
653
		unset($config['interfaces']['lan']['bandwidth']);
654
		unset($config['interfaces']['lan']['bandwidthtype']);		
655
		$config['shaper']['enable'] = FALSE;
656
		$config['version'] = "1.7";	
657
	}
658 1425e067 Bill Marquette
	/* Convert 1.7 -> 1.8 */
659
	if ($config['version'] == "1.7") {
660
		if(isset($config['proxyarp']) && is_array($config['proxyarp']['proxyarpnet'])) {
661
			$proxyarp = &$config['proxyarp']['proxyarpnet'];
662
			foreach($proxyarp as $arpent){
663
				$vip = array();
664
				$vip['mode'] = "proxyarp";
665
				$vip['interface'] = $arpent['interface'];
666
				$vip['descr'] = $arpent['descr'];
667
				if (isset($arpent['range'])) {
668
					$vip['range'] = $arpent['range'];
669
					$vip['type'] = "range";
670
				} else {
671
					$subnet = explode('/', $arpent['network']);
672
					$vip['subnet'] = $subnet[0];
673
					if (isset($subnet[1])) {
674
						$vip['subnet_bits'] = $subnet[1];
675
						$vip['type'] = "network";
676
					} else {
677
						$vip['subnet_bits'] = "32";
678
						$vip['type'] = "single";
679
					}
680
				}
681
				$config['virtualip']['vip'][] = $vip;
682
			}
683
			unset($config['proxyarp']);
684
		}
685
		if(isset($config['installedpackages']) && isset($config['installedpackages']['carp']) && is_array($config['installedpackages']['carp']['config'])) {
686
			$carp = &$config['installedpackages']['carp']['config'];
687
			foreach($carp as $carpent){
688
				$vip = array();
689
				$vip['mode'] = "carp";
690
				$vip['interface'] = "AUTO";
691
				$vip['descr'] = "CARP vhid {$carpent['vhid']}";
692
				$vip['type'] = "single";
693
				$vip['vhid'] = $carpent['vhid'];
694
				$vip['advskew'] = $carpent['advskew'];
695
				$vip['password'] = $carpent['password'];
696
				$vip['subnet'] = $carpent['ipaddress'];
697 c153d430 Bill Marquette
				$vip['subnet_bits'] = $carpent['netmask'];
698 1425e067 Bill Marquette
				$config['virtualip']['vip'][] = $vip;
699
			}
700
			unset($config['installedpackages']['carp']);
701
		}
702 e82f32ef Bill Marquette
		/* Server NAT is no longer needed */
703
		unset($config['nat']['servernat']);
704 1425e067 Bill Marquette
		
705 e4662fc5 Scott Ullrich
		/* enable SSH */
706
		if ($config['version'] == "1.8") {
707
			$config['system']['sshenabled'] = true;
708
		}
709
		
710
		$config['version'] = "1.9";
711 1425e067 Bill Marquette
	}
712 e42cac89 Scott Ullrich
713
	/* Convert 1.8 -> 1.9 */
714 8cfa169c Scott Ullrich
	if ($config['version'] == "1.8") {
715 e42cac89 Scott Ullrich
		$config['theme']="metallic";
716
		$config['version'] = "1.9";
717
	}
718 1a82cbcb Bill Marquette
	/* Convert 1.9 -> 2.0 */
719 faee6cd6 Bill Marquette
	if ($config['version'] == "1.9") {
720
		if(is_array($config['ipsec']['tunnel'])) {
721
			reset($config['ipsec']['tunnel']);
722 0e8f4e7b Bill Marquette
			while (list($index, $tunnel) = each($config['ipsec']['tunnel'])) {
723 faee6cd6 Bill Marquette
				/* Sanity check on required variables */
724
				/* This fixes bogus <tunnel> entries - remnant of bug #393 */
725
				if (!isset($tunnel['local-subnet']) && !isset($tunnel['remote-subnet'])) {
726
					unset($config['ipsec']['tunnel'][$tunnel]);
727
				}
728
			}
729
        	}
730 6823bfb6 Scott Ullrich
		$config['version'] = "2.0";
731 faee6cd6 Bill Marquette
	}
732 0f20c092 Bill Marquette
	/* Convert 2.0 -> 2.1 */
733
	if ($config['version'] == "2.0") {
734
		/* shaper scheduler moved */
735
		if(isset($config['system']['schedulertype'])) {
736
			$config['shaper']['schedulertype'] = $config['system']['schedulertype'];
737
			unset($config['system']['schedulertype']);
738
		}
739
		$config['version'] = "2.1";
740
	}
741 1325678b Scott Ullrich
	/* Convert 2.1 -> 2.2 */
742
	if ($config['version'] == "2.1") {
743
		/* move gateway to wan interface */
744
		$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
745
		$config['version'] = "2.2";
746
	}
747 45cb953d Colin Smith
748 d05dff82 Bill Marquette
	if ($prev_version != $config['version'])
749 fc13ca75 Bill Marquette
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
750 5b237745 Scott Ullrich
}
751
752 840c97dc Colin Smith
/****f* config/write_config
753
 * NAME
754
 *   write_config - Backup and write the firewall configuration.
755
 * DESCRIPTION
756
 *   write_config() handles backing up the current configuration,
757
 *   applying changes, and regenerating the configuration cache.
758
 * INPUTS
759
 *   $desc	- string containing the a description of configuration changes
760
 *   $backup	- boolean: do not back up current configuration if false.
761
 * RESULT
762
 *   null       
763
 ******/
764 5b237745 Scott Ullrich
/* save the system configuration */
765 41508358 Scott Ullrich
function write_config($desc="Unknown", $backup = true) {
766 5b237745 Scott Ullrich
	global $config, $g;
767
768 e9881b87 Scott Ullrich
	if($g['platform'] <> "embedded" and $g['platform'] <> "wrap") 
769 ac24ba53 Scott Ullrich
		if($backup) backup_config();
770 5b237745 Scott Ullrich
771 41508358 Scott Ullrich
	if (time() > mktime(0, 0, 0, 9, 1, 2004))       /* make sure the clock settings are plausible */
772
                $changetime = time();
773 a331fd27 Colin Smith
774 41508358 Scott Ullrich
	/* Log the running script so it's not entirely unlogged what changed */ 
775
        if ($desc == "Unknown") 
776
        	$desc = "{$_SERVER['SCRIPT_NAME']} made unknown change";  
777 b638fcfd Colin Smith
778 41508358 Scott Ullrich
	$config['revision']['description'] = $desc;
779
	$config['revision']['time'] = $changetime;
780
	
781
	config_lock();
782 5b237745 Scott Ullrich
783
	/* generate configuration XML */
784
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
785
786 04daa3c6 Scott Ullrich
	conf_mount_rw();
787
788 41508358 Scott Ullrich
	/* write new configuration */
789 5b237745 Scott Ullrich
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
790
	if (!$fd)
791 2e523ffe Bill Marquette
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
792 5b237745 Scott Ullrich
	fwrite($fd, $xmlconfig);
793
	fclose($fd);
794
795 bc89f7d3 Scott Ullrich
	if($g['booting'] <> true) {
796 02facbd0 Scott Ullrich
		conf_mount_ro();
797
	}
798
799 5b237745 Scott Ullrich
	config_unlock();
800 412ebed9 Bill Marquette
801 7cc29855 Colin Smith
	// Always reparse the config after it's written - something is getting lost in serialize().
802 1b720c35 Colin Smith
	$config = parse_config(true);
803 917d4a96 Colin Smith
	return $config;
804 5b237745 Scott Ullrich
}
805
806 840c97dc Colin Smith
/****f* config/reset_factory_defaults
807
 * NAME
808
 *   reset_factory_defaults - Reset the system to its default configuration.
809
 * RESULT
810
 *   integer	- indicates completion
811
 ******/
812 5b237745 Scott Ullrich
function reset_factory_defaults() {
813
	global $g;
814
815
	config_lock();
816
	conf_mount_rw();
817
818
	/* create conf directory, if necessary */
819 d058b0be Colin Smith
	safe_mkdir("{$g['cf_conf_path']}");
820 5b237745 Scott Ullrich
821
	/* clear out /conf */
822
	$dh = opendir($g['conf_path']);
823
	while ($filename = readdir($dh)) {
824
		if (($filename != ".") && ($filename != "..")) {
825 e50b0c5d Bill Marquette
			unlink_if_exists($g['conf_path'] . "/" . $filename);
826 5b237745 Scott Ullrich
		}
827
	}
828
	closedir($dh);
829
830
	/* copy default configuration */
831 e50b0c5d Bill Marquette
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
832 4973d941 Scott Ullrich
	
833
	/* call the wizard */
834 cb21eb7b Scott Ullrich
	touch("/conf/trigger_initial_wizard");
835 4973d941 Scott Ullrich
	
836 5b237745 Scott Ullrich
	conf_mount_ro();
837
	config_unlock();
838
839
	return 0;
840
}
841
842 41508358 Scott Ullrich
function config_restore($conffile) {
843 5b237745 Scott Ullrich
	global $config, $g;
844 1f4adc3e Colin Smith
       
845 41508358 Scott Ullrich
        if (!file_exists($conffile))
846
                return 1;
847
        
848
        config_lock();
849
        conf_mount_rw();        
850
        
851
        backup_config();
852 1f4adc3e Colin Smith
        copy($conffile, "{$g['cf_conf_path']}/config.xml");
853
	$config = parse_config(true);
854 41508358 Scott Ullrich
        write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
855
        
856
        conf_mount_ro();
857
        config_unlock();
858
859
        return 0;
860
}
861 5b237745 Scott Ullrich
862 ffd1b445 Scott Ullrich
863
864 41508358 Scott Ullrich
function config_install($conffile) {
865
        global $config, $g;
866
        
867
        if (!file_exists($conffile))
868
                return 1;
869 7f8d1f3f Scott Ullrich
870 5af3e206 Scott Ullrich
	if (!config_validate($conffile))
871
		return 1;
872
873 7f8d1f3f Scott Ullrich
	if($g['booting'] == true)
874
		echo "Installing configuration...\n";
875 41508358 Scott Ullrich
 
876
        config_lock();
877
        conf_mount_rw();
878 80c02328 Scott Ullrich
879
	
880 41508358 Scott Ullrich
        copy($conffile, "{$g['conf_path']}/config.xml");
881 80c02328 Scott Ullrich
882
	/* unlink cache file if it exists */
883
	if(file_exists("{$g['tmp_path']}/config.cache"))
884
		unlink("{$g['tmp_path']}/config.cache");
885
  
886 41508358 Scott Ullrich
        conf_mount_ro();
887
        config_unlock();
888
889
        return 0;
890 5b237745 Scott Ullrich
}
891
892 5af3e206 Scott Ullrich
function config_validate($conffile) {
893
894
	global $g, $xmlerr;
895
896
	$xml_parser = xml_parser_create();
897
	
898
	if (!($fp = fopen($conffile, "r"))) {
899
		$xmlerr = "XML error: unable to open file";
900
		return false;
901
	}
902
	
903
	while ($data = fread($fp, 4096)) {
904
		if (!xml_parse($xml_parser, $data, feof($fp))) {
905
			$xmlerr = sprintf("%s at line %d",
906
						xml_error_string(xml_get_error_code($xml_parser)),
907
						xml_get_current_line_number($xml_parser));
908
			return false;
909
		}
910
	}
911
	xml_parser_free($xml_parser);
912
	
913
	fclose($fp);
914
	
915
	return true;
916
}
917
918 5b237745 Scott Ullrich
/* lock configuration file, decide that the lock file is stale after
919
   10 seconds */
920
function config_lock() {
921 7cf78912 Bill Marquette
	global $g, $process_lock;
922 5b237745 Scott Ullrich
923 7cf78912 Bill Marquette
	/* No need to continue if we're the ones holding the lock */
924
	if ($process_lock)
925
		return;
926 5b237745 Scott Ullrich
927
	$lockfile = "{$g['varrun_path']}/config.lock";
928
929
	$n = 0;
930
	while ($n < 10) {
931
		/* open the lock file in append mode to avoid race condition */
932
		if ($fd = @fopen($lockfile, "x")) {
933
			/* succeeded */
934 7cf78912 Bill Marquette
			$process_lock = true;
935 5b237745 Scott Ullrich
			fclose($fd);
936
			return;
937
		} else {
938
			/* file locked, wait and try again */
939 7cf78912 Bill Marquette
			$process_lock = false;
940 5b237745 Scott Ullrich
			sleep(1);
941
			$n++;
942
		}
943
	}
944
}
945
946
/* unlock configuration file */
947
function config_unlock() {
948 7cf78912 Bill Marquette
	global $g, $process_lock;
949 5b237745 Scott Ullrich
950
	$lockfile = "{$g['varrun_path']}/config.lock";
951 7cf78912 Bill Marquette
	$process_lock = false;
952 5b237745 Scott Ullrich
953 e50b0c5d Bill Marquette
	unlink_if_exists($lockfile);
954 5b237745 Scott Ullrich
}
955
956 afe53428 Scott Ullrich
function set_networking_interfaces_ports() {
957 bb17ff99 Scott Ullrich
	global $noreboot;
958 c1666878 Scott Ullrich
	global $config;
959
	global $g;
960 e522f83c Scott Ullrich
	global $fp;
961 bb17ff99 Scott Ullrich
962 afe53428 Scott Ullrich
	$fp = fopen('php://stdin', 'r');
963
964 4fde4ce4 Colin Smith
	$iflist = get_interface_list();
965 afe53428 Scott Ullrich
966
	echo <<<EOD
967
968
Valid interfaces are:
969
970
971
EOD;
972
973 1d9118a1 Scott Ullrich
	if(!is_array($iflist)) {
974
		echo "No interfaces found!\n";
975
	} else {
976
		foreach ($iflist as $iface => $ifa) {
977
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
978
				$ifa['up'] ? "   (up)" : "");
979
		}
980 afe53428 Scott Ullrich
	}
981
982
	echo <<<EOD
983
984
Do you want to set up VLANs first?
985 763f6238 Scott Ullrich
If you are not going to use VLANs, or only for optional interfaces, you
986 afe53428 Scott Ullrich
should say no here and use the webGUI to configure VLANs later, if required.
987
988
Do you want to set up VLANs now [y|n]?
989
EOD;
990
991
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
992
		vlan_setup();
993
994
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
995
996
		echo "\n\nVLAN interfaces:\n\n";
997
		$i = 0;
998
		foreach ($config['vlans']['vlan'] as $vlan) {
999
1000
			echo sprintf("% -8s%s\n", "vlan{$i}",
1001
				"VLAN tag {$vlan['tag']}, interface {$vlan['if']}");
1002
1003
			$iflist['vlan' . $i] = array();
1004
			$i++;
1005
		}
1006
	}
1007
1008
	echo <<<EOD
1009
1010 4fde4ce4 Colin Smith
*NOTE*  pfSense requires *ATLEAST* 2 assigned interfaces to function.
1011
        If you do not have two interfaces turn off the machine until
1012
	you do.
1013
1014 763f6238 Scott Ullrich
If you do not know the names of your interfaces, you may choose to use
1015 03efea5e Scott Ullrich
auto-detection... In that case, disconnect all interfaces now before
1016
hitting a.   The system will then prompt you to plug in each nic to
1017
autodetect.
1018 afe53428 Scott Ullrich
1019
EOD;
1020
1021
	do {
1022
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
1023
		$lanif = chop(fgets($fp));
1024
		if ($lanif === "") {
1025 e196278c Scott Ullrich
			return;
1026 afe53428 Scott Ullrich
		}
1027
1028
		if ($lanif === "a")
1029
			$lanif = autodetect_interface("LAN", $fp);
1030
		else if (!array_key_exists($lanif, $iflist)) {
1031
			echo "\nInvalid interface name '{$lanif}'\n";
1032
			unset($lanif);
1033
			continue;
1034
		}
1035
	} while (!$lanif);
1036
1037
	do {
1038
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
1039
		$wanif = chop(fgets($fp));
1040
		if ($wanif === "") {
1041 e196278c Scott Ullrich
			return;
1042 afe53428 Scott Ullrich
		}
1043
		if ($wanif === "a")
1044
			$wanif = autodetect_interface("WAN", $fp);
1045
		else if (!array_key_exists($wanif, $iflist)) {
1046
			echo "\nInvalid interface name '{$wanif}'\n";
1047
			unset($wanif);
1048
			continue;
1049
		}
1050
	} while (!$wanif);
1051
1052
	/* optional interfaces */
1053
	$i = 0;
1054
	$optif = array();
1055
1056
	while (1) {
1057
		if ($optif[$i])
1058
			$i++;
1059
		$i1 = $i + 1;
1060
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1061
			"(or nothing if finished): ";
1062
		$optif[$i] = chop(fgets($fp));
1063
1064
		if ($optif[$i]) {
1065
			if ($optif[$i] === "a") {
1066
				$ad = autodetect_interface("Optional " . $i1, $fp);
1067
				if ($ad)
1068
					$optif[$i] = $ad;
1069
				else
1070
					unset($optif[$i]);
1071
			} else if (!array_key_exists($optif[$i], $iflist)) {
1072
				echo "\nInvalid interface name '{$optif[$i]}'\n";
1073
				unset($optif[$i]);
1074
				continue;
1075
			}
1076
		} else {
1077
			unset($optif[$i]);
1078
			break;
1079
		}
1080
	}
1081
1082
	/* check for double assignments */
1083
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1084
1085
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1086
		for ($j = ($i+1); $j < count($ifarr); $j++) {
1087
			if ($ifarr[$i] == $ifarr[$j]) {
1088
				echo <<<EOD
1089
1090 763f6238 Scott Ullrich
Error: you cannot assign the same interface name twice!
1091 afe53428 Scott Ullrich
1092
EOD;
1093
1094 e196278c Scott Ullrich
				return;
1095 afe53428 Scott Ullrich
			}
1096
		}
1097
	}
1098
1099
	echo <<<EOD
1100
1101
The interfaces will be assigned as follows:
1102
1103
LAN  -> {$lanif}
1104
WAN  -> {$wanif}
1105
1106
EOD;
1107
1108
	for ($i = 0; $i < count($optif); $i++) {
1109
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1110
	}
1111
1112 bb17ff99 Scott Ullrich
echo <<<EOD
1113 afe53428 Scott Ullrich
1114
Do you want to proceed [y|n]?
1115
EOD;
1116
1117
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1118
1119
		$config['interfaces']['lan']['if'] = $lanif;
1120 fd91e85c Scott Ullrich
		if (preg_match($g['wireless_regex'], $lanif)) {
1121 afe53428 Scott Ullrich
			if (!is_array($config['interfaces']['lan']['wireless']))
1122
				$config['interfaces']['lan']['wireless'] = array();
1123
		} else {
1124
			unset($config['interfaces']['lan']['wireless']);
1125
		}
1126 fd91e85c Scott Ullrich
		
1127 afe53428 Scott Ullrich
		$config['interfaces']['wan']['if'] = $wanif;
1128 fd91e85c Scott Ullrich
		if (preg_match($g['wireless_regex'], $wanif)) {
1129 afe53428 Scott Ullrich
			if (!is_array($config['interfaces']['wan']['wireless']))
1130
				$config['interfaces']['wan']['wireless'] = array();
1131
		} else {
1132
			unset($config['interfaces']['wan']['wireless']);
1133
		}
1134 fd91e85c Scott Ullrich
		
1135 afe53428 Scott Ullrich
		for ($i = 0; $i < count($optif); $i++) {
1136
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
1137
				$config['interfaces']['opt' . ($i+1)] = array();
1138 fd91e85c Scott Ullrich
			
1139 afe53428 Scott Ullrich
			$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
1140 fd91e85c Scott Ullrich
			
1141 afe53428 Scott Ullrich
			/* wireless interface? */
1142 fd91e85c Scott Ullrich
			if (preg_match($g['wireless_regex'], $optif[$i])) {
1143 afe53428 Scott Ullrich
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
1144
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
1145
			} else {
1146
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
1147
			}
1148 fd91e85c Scott Ullrich
			
1149 afe53428 Scott Ullrich
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
1150
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
1151
		}
1152 fd91e85c Scott Ullrich
		
1153 afe53428 Scott Ullrich
		/* remove all other (old) optional interfaces */
1154
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
1155
			unset($config['interfaces']['opt' . ($i+1)]);
1156 fd91e85c Scott Ullrich
		
1157 4973d941 Scott Ullrich
		conf_mount_rw();
1158
		
1159
		/* call the wizard */
1160 cb21eb7b Scott Ullrich
		touch("/conf/trigger_initial_wizard");
1161 4973d941 Scott Ullrich
		
1162 fd91e85c Scott Ullrich
		write_config();
1163
		
1164 afe53428 Scott Ullrich
		echo <<<EOD
1165
1166 bb17ff99 Scott Ullrich
1167 afe53428 Scott Ullrich
1168
EOD;
1169 0912a5f5 Scott Ullrich
1170 82958e6d Scott Ullrich
		if($g['booting'])
1171 cf1aa877 Scott Ullrich
			return;
1172 0912a5f5 Scott Ullrich
1173 01622555 Scott Ullrich
		echo "One moment while we reload the settings...";
1174 71c5821b Scott Ullrich
1175 43637d9e Scott Ullrich
		/* resync everything */
1176
		reload_all_sync();
1177 71c5821b Scott Ullrich
		
1178 111207b5 Scott Ullrich
		echo " done!\n";
1179 76612f46 Scott Ullrich
		
1180
		touch("{$g['tmp_path']}/assign_complete");
1181 afe53428 Scott Ullrich
1182
	}
1183 1fc6d183 Scott Ullrich
}
1184 afe53428 Scott Ullrich
1185 1fc6d183 Scott Ullrich
function autodetect_interface($ifname, $fp) {
1186 9249b756 Colin Smith
	$iflist_prev = get_interface_list("media");
1187 1fc6d183 Scott Ullrich
	echo <<<EOD
1188 afe53428 Scott Ullrich
1189
Connect the {$ifname} interface now and make sure that the link is up.
1190
Then press ENTER to continue.
1191
1192
EOD;
1193 1fc6d183 Scott Ullrich
	fgets($fp);
1194 9249b756 Colin Smith
	$iflist = get_interface_list("media");
1195 4fde4ce4 Colin Smith
1196 1fc6d183 Scott Ullrich
	foreach ($iflist_prev as $ifn => $ifa) {
1197
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
1198
			echo "Detected link-up on interface {$ifn}.\n";
1199
			return $ifn;
1200 afe53428 Scott Ullrich
		}
1201
	}
1202
1203 1fc6d183 Scott Ullrich
	echo "No link-up detected.\n";
1204
1205
	return null;
1206 e522f83c Scott Ullrich
}
1207 afe53428 Scott Ullrich
1208 e522f83c Scott Ullrich
function vlan_setup() {
1209
	global $iflist, $config, $g, $fp;
1210 afe53428 Scott Ullrich
1211 d8dc587b Scott Ullrich
	$iflist = get_interface_list();
1212
1213 e522f83c Scott Ullrich
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1214
1215
	echo <<<EOD
1216 afe53428 Scott Ullrich
1217
WARNING: all existing VLANs will be cleared if you proceed!
1218
1219
Do you want to proceed [y|n]?
1220
EOD;
1221
1222 e522f83c Scott Ullrich
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
1223
		return;
1224
	}
1225 afe53428 Scott Ullrich
1226 e522f83c Scott Ullrich
	$config['vlans']['vlan'] = array();
1227
	echo "\n";
1228 afe53428 Scott Ullrich
1229 e522f83c Scott Ullrich
	while (1) {
1230
		$vlan = array();
1231 afe53428 Scott Ullrich
1232 7695ef3f Scott Ullrich
		echo "\n\nVLAN Capable interfaces:\n\n";
1233
		if(!is_array($iflist)) {
1234
			echo "No interfaces found!\n";
1235
		} else {
1236
			$vlan_capable=0;
1237
			foreach ($iflist as $iface => $ifa) {
1238 0ed78ddb Scott Ullrich
				if (is_jumbo_capable($iface)) {
1239 7695ef3f Scott Ullrich
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1240
						$ifa['up'] ? "   (up)" : "");
1241
					$vlan_capable++;
1242
				}
1243
			}
1244
		}
1245
1246
		if($vlan_capable == 0) {
1247
			echo "No VLAN capable interfaces detected.\n";
1248
			return;
1249
		}
1250
1251 e522f83c Scott Ullrich
		echo "\nEnter the parent interface name for the new VLAN (or nothing if finished): ";
1252
		$vlan['if'] = chop(fgets($fp));
1253 afe53428 Scott Ullrich
1254 e522f83c Scott Ullrich
		if ($vlan['if']) {
1255 6a32d1e5 Scott Ullrich
			if (!array_key_exists($vlan['if'], $iflist) or
1256
			    !is_jumbo_capable($vlan['if'])) {
1257 e522f83c Scott Ullrich
				echo "\nInvalid interface name '{$vlan['if']}'\n";
1258 afe53428 Scott Ullrich
				continue;
1259
			}
1260 e522f83c Scott Ullrich
		} else {
1261
			break;
1262
		}
1263
1264
		echo "Enter the VLAN tag (1-4094): ";
1265
		$vlan['tag'] = chop(fgets($fp));
1266 afe53428 Scott Ullrich
1267 e522f83c Scott Ullrich
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
1268
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
1269
			continue;
1270 afe53428 Scott Ullrich
		}
1271 e522f83c Scott Ullrich
1272
		$config['vlans']['vlan'][] = $vlan;
1273 afe53428 Scott Ullrich
	}
1274
}
1275
1276 dd78523c Scott Ullrich
function system_start_ftp_helpers() {
1277 613bdee0 Scott Ullrich
	require_once("interfaces.inc");
1278 5c6d0f65 Colin Smith
	global $config, $g;
1279 6873a9a4 Scott Ullrich
1280 c1ec2c2f Scott Ullrich
	/* build an array of interfaces to work with */
1281 bcd3f3ad Scott Ullrich
	$iflist = array("lan" => "LAN");
1282 c1ec2c2f Scott Ullrich
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
1283
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1284
1285
	/* loop through all interfaces and handle pftpx */
1286
	$interface_counter = 0;
1287
	foreach ($iflist as $ifent => $ifname) {
1288
		/*    if the ftp proxy is disabled for this interface then kill pftpx 
1289
		 *    instance and continue. note that the helpers for port forwards are 
1290
		 *    launched in a  different sequence so we are filtering them out 
1291
                 *    here by not including -c {$port} -g 8021 first.
1292
		 */
1293
		$port = 8021 + $interface_counter;
1294 328637fe Scott Ullrich
		if(isset($config['interfaces'][strtolower($ifname)]['disableftpproxy'])) {
1295 c1ec2c2f Scott Ullrich
			/*    item is disabled.  lets ++ the interface counter and
1296
			 *    keep processing interfaces. kill pftpx if already
1297
                         *    running for this instance.
1298
                         */
1299 6a3464b7 Scott Ullrich
			$helpers = exec("ps awux | grep \"/usr/local/sbin/pftpx -c {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
1300 b1f23568 Scott Ullrich
			if($helpers)
1301
				mwexec("/bin/kill {$helpers}");
1302 c1ec2c2f Scott Ullrich
			$interface_counter++;
1303 5c1fd1d9 Scott Ullrich
		} else {
1304 1324a93a Scott Ullrich
			/* grab the current interface IP address */
1305 6d648622 Scott Ullrich
			$int = convert_friendly_interface_to_real_interface_name($ifname);
1306
			$ip = find_interface_ip($int);
1307 5c1fd1d9 Scott Ullrich
			/* if pftpx is already running then do not launch it again */
1308 6d648622 Scott Ullrich
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/pftpx -c {$port}\" | grep -v grep | sed \"s/  */ /g\"");
1309 1324a93a Scott Ullrich
			if(!$helpers && $ip)
1310 b1f23568 Scott Ullrich
 				mwexec("/usr/local/sbin/pftpx -c {$port} -g 8021 {$ip}");
1311 5c1fd1d9 Scott Ullrich
			$interface_counter++;
1312
		}
1313 dce949b0 Scott Ullrich
	}
1314 dd78523c Scott Ullrich
}
1315
1316 7cc29855 Colin Smith
function cleanup_backupcache($revisions = 30) {
1317 392a9bb8 Colin Smith
	global $g;
1318 41508358 Scott Ullrich
	$i = false;
1319 dc74c78a Colin Smith
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1320 3fd7c6af Scott Ullrich
		conf_mount_rw();
1321 dc74c78a Colin Smith
		$backups = get_backups();
1322
		$newbaks = array();
1323 8a421967 Colin Smith
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
1324 dc74c78a Colin Smith
		$baktimes = $backups['versions'];
1325
		$tocache = array();
1326
		unset($backups['versions']);
1327
       		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
1328
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));	
1329
                	if(!in_array($tocheck, $baktimes)) {
1330
				$i = true;
1331 346089b0 Scott Ullrich
				if($g['booting']) print " " . $tocheck . "a";
1332 dc74c78a Colin Smith
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
1333
				if($newxml['revision']['description'] == "") $newxml['revision']['description'] = "Unknown";
1334
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
1335
			}
1336
        	}
1337
		foreach($backups as $checkbak) {
1338
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
1339
				$newbaks[] = $checkbak;
1340
			} else {
1341
				$i = true;
1342 346089b0 Scott Ullrich
				if($g['booting']) print " " . $tocheck . "r";
1343 dc74c78a Colin Smith
			}
1344 41508358 Scott Ullrich
		}
1345 dc74c78a Colin Smith
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);	
1346 7cc29855 Colin Smith
		if(is_int($revisions) and (count($tocache) > $revisions)) {
1347 dc74c78a Colin Smith
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
1348
			foreach($toslice as $sliced) $newcache[$sliced] = $tocache[$sliced];
1349
			foreach($tocache as $version => $versioninfo) {
1350
				if(!in_array($version, array_keys($newcache))) {
1351
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
1352 346089b0 Scott Ullrich
					if($g['booting']) print " " . $tocheck . "d";
1353 dc74c78a Colin Smith
				}
1354 41508358 Scott Ullrich
			}
1355 dc74c78a Colin Smith
			$tocache = $newcache;
1356 41508358 Scott Ullrich
		}
1357 dc74c78a Colin Smith
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1358
        	fwrite($bakout, serialize($tocache));
1359
  	        fclose($bakout);
1360 3fd7c6af Scott Ullrich
		conf_mount_ro();
1361 41508358 Scott Ullrich
	}
1362 5c6d0f65 Colin Smith
	if($g['booting']) {
1363 41508358 Scott Ullrich
		if($i) {
1364 deebaae1 Scott Ullrich
			print "done.\n";
1365 41508358 Scott Ullrich
		}
1366
	}
1367
}
1368
  	 
1369
function get_backups() { 	 
1370 e50b0c5d Bill Marquette
	global $g;
1371
1372 7e0e716a Bill Marquette
        if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1373
                $confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1374 41508358 Scott Ullrich
		$bakvers = array_keys($confvers);
1375
		$toreturn = array();
1376
		sort($bakvers);
1377
		// $bakvers = array_reverse($bakvers);
1378
		foreach(array_reverse($bakvers) as $bakver) $toreturn[] = array('time' => $bakver,
1379
								 'description' => $confvers[$bakver]['description']
1380
								);
1381
        } else { 	 
1382
                return false; 	 
1383
        }
1384
	$toreturn['versions'] = $bakvers;
1385
        return $toreturn;
1386
}
1387 926312b6 Colin Smith
1388 41508358 Scott Ullrich
function backup_config() {
1389
	global $config, $g;
1390 e50b0c5d Bill Marquette
1391 8fb3a072 Scott Ullrich
	if($g['platform'] == "cdrom")
1392
		return;
1393
1394 865e08c2 Scott Ullrich
	conf_mount_rw();
1395
1396 e50b0c5d Bill Marquette
	/* Create backup directory if needed */
1397
	safe_mkdir("{$g['cf_conf_path']}/backup");
1398
1399 d058b0be Colin Smith
        if($config['revision']['time'] == "") {
1400 41508358 Scott Ullrich
                $baktime = 0;
1401 d058b0be Colin Smith
        } else {
1402 41508358 Scott Ullrich
                $baktime = $config['revision']['time'];
1403 d058b0be Colin Smith
        }
1404
        if($config['revision']['description'] == "") {
1405 41508358 Scott Ullrich
                $bakdesc = "Unknown";
1406 d058b0be Colin Smith
        } else {
1407 41508358 Scott Ullrich
                $bakdesc = $config['revision']['description'];
1408 d058b0be Colin Smith
        }
1409
        copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
1410
        if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1411 41508358 Scott Ullrich
                $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1412 d058b0be Colin Smith
        } else {
1413 41508358 Scott Ullrich
                $backupcache = array();
1414 d058b0be Colin Smith
        }
1415 41508358 Scott Ullrich
        $backupcache[$baktime] = array('description' => $bakdesc);
1416 d058b0be Colin Smith
        $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1417
        fwrite($bakout, serialize($backupcache));
1418
        fclose($bakout);
1419 865e08c2 Scott Ullrich
	
1420
	conf_mount_ro();
1421
	
1422 41508358 Scott Ullrich
	return true;
1423
}
1424 dd2ab8f8 Scott Ullrich
1425
function mute_kernel_msgs() {
1426
	exec("/sbin/conscontrol mute on");
1427
}
1428
1429
function unmute_kernel_msgs() {
1430
	exec("/sbin/conscontrol mute off");
1431
}
1432
1433 caeb3b46 Scott Ullrich
function start_devd() {
1434
	exec("/sbin/devd");
1435
}
1436
1437 7695ef3f Scott Ullrich
?>