Project

General

Profile

Download (59.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****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
	config.inc
12
	Copyright (C) 2004-2006 Scott Ullrich
13
	All rights reserved.
14

    
15
	originally part of m0n0wall (http://m0n0.ch/wall)
16
	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
if($g['booting']) echo ".";
42

    
43
/* do not load this file twice. */
44
if($config_inc_loaded == true)
45
	return;
46
else
47
	$config_inc_loaded = true;
48

    
49
/* include globals/utility/XML parser files */
50
require_once("globals.inc");
51
if($g['booting']) echo ".";
52
require_once("util.inc");
53
if($g['booting']) echo ".";
54
require_once("pfsense-utils.inc");
55
if($g['booting']) echo ".";
56
require_once("xmlparse.inc");
57
if($g['booting']) echo ".";
58
require_once("services.inc");
59

    
60
/* read platform */
61
if($g['booting']) echo ".";
62
if (file_exists("{$g['etc_path']}/platform")) {
63
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
64
} else {
65
	$g['platform'] = "unknown";
66
}
67

    
68
/* if /debugging exists, lets set $debugging
69
   so we can output more information */
70
if(file_exists("/debugging")) {
71
	$debugging = true;
72
	$g['debug'] = true;
73
}
74

    
75
if($g['booting']) echo ".";
76
if(file_exists("/cf/conf/config.xml")) {
77
	$config_contents = file_get_contents("/cf/conf/config.xml");
78
	if(stristr($config_contents, "<m0n0wall>") == true) {
79
		if($g['booting']) echo ".";
80
		/* user has just upgraded to m0n0wall, replace root xml tags */
81
		log_error("Upgrading m0n0wall configuration to pfSense... ");
82
		$config_contents = str_replace("m0n0wall","pfsense", $config_contents);
83
		if (!config_validate("{$g['conf_path']}/config.xml"))
84
			log_error("ERROR!  Could not convert m0n0wall -> pfsense in config.xml");
85
		conf_mount_rw();
86
		$fd = fopen("/cf/conf/config.xml", "w");
87
		fwrite($fd, $config_contents);
88
		fclose($fd);
89
		conf_mount_ro();
90
	}
91
}
92

    
93
/* if our config file exists bail out, we're already set. */
94
if ($g['booting'] and !file_exists($g['cf_conf_path'] . "/config.xml")  ) {
95
	if($g['booting']) echo ".";
96
	/* find the device where config.xml resides and write out an fstab */
97
	unset($cfgdevice);
98
	if($g['booting']) echo ".";
99
	/* check if there's already an fstab (NFS booting?) */
100
	if (!file_exists("{$g['etc_path']}/fstab")) {
101
		if($g['booting']) echo ".";
102
		if (strstr($g['platform'], "cdrom")) {
103
			/* config is on floppy disk for CD-ROM version */
104
			$cfgdevice = $cfgpartition = "fd0";
105
			$dmesg = `dmesg -a`;
106
			if(ereg("da0", $dmesg) == true) {
107
				$cfgdevice = $cfgpartition = "da0" ;
108
				if (mwexec("/sbin/mount -r /dev/{$cfgdevice} /cf")) {
109
					/* could not mount, fallback to floppy */
110
					$cfgdevice = $cfgpartition = "fd0";
111
				}
112
			}
113
			$cfgfstype = "msdos";
114
			echo "CDROM build\n";
115
			echo "   CFG: {$cfgpartition}\n";
116
			echo "  TYPE: {$cfgfstype}\n";
117
		} else {
118
			if($g['booting']) echo ".";
119
			/* probe kernel known disks until we find one with config.xml */
120
			$disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
121
			foreach ($disks as $mountdisk) {
122
				/* skip mfs mounted filesystems */
123
				if (strstr($mountdisk, "md"))
124
					continue;
125
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
126
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
127
						/* found it */
128
						$cfgdevice = $mountdisk;
129
						$cfgpartition = $cfgdevice . "a";
130
						$cfgfstype = "ufs";
131
						echo "Found configuration on $cfgdevice.\n";
132
					}
133

    
134
					mwexec("/sbin/umount -f {$g['cf_path']}");
135

    
136
					if ($cfgdevice)
137
						break;
138
				}
139
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}d {$g['cf_path']}") == 0) {
140
					if($g['booting']) echo ".";
141
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
142
						/* found it */
143
						$cfgdevice = $mountdisk;
144
						$cfgpartition = $cfgdevice . "d";
145
						$cfgfstype = "ufs";
146
						echo "Found configuration on $cfgdevice.\n";
147
					}
148

    
149
					mwexec("/sbin/umount -f {$g['cf_path']}");
150

    
151
					if ($cfgdevice)
152
						break;
153
				}
154
			}
155
		}
156
		if($g['booting']) echo ".";
157
		if (!$cfgdevice) {
158
			$last_backup = discover_last_backup();
159
			if($last_backup) {
160
				log_error("No config.xml found, attempting last known config restore.");
161
				file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
162
				restore_backup("/cf/conf/backup/{$last_backup}");
163
			} else {
164
				/* no device found, print an error and die */
165
				echo <<<EOD
166

    
167
*******************************************************************************
168
* FATAL ERROR                                                                 *
169
* The device that contains the configuration file (config.xml) could not be   *
170
* found. pfSense cannot continue booting.                                     *
171
*******************************************************************************
172

    
173

    
174
EOD;
175

    
176
				mwexec("/sbin/halt");
177
				exit;
178
			}
179
		}
180

    
181
		/* write device name to a file for rc.firmware */
182
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
183
		fwrite($fd, $cfgdevice . "\n");
184
		fclose($fd);
185

    
186
		/* write out an fstab */
187
		$fd = fopen("{$g['etc_path']}/fstab", "w");
188

    
189
		$fstab = "/dev/{$cfgpartition} {$g['cf_path']} {$cfgfstype} ro 1 1\n";
190
		$fstab .= "proc /proc procfs rw 0 0\n";
191

    
192
		fwrite($fd, $fstab);
193
		fclose($fd);
194
	}
195
	if($g['booting']) echo ".";
196
	/* mount all filesystems */
197
	mwexec("/sbin/mount -a");
198
}
199

    
200
/****f* config/parse_config
201
 * NAME
202
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
203
 * INPUTS
204
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
205
 * RESULT
206
 *   $config      - array containing all configuration variables
207
 ******/
208
function parse_config($parse = false) {
209
	global $g;
210
	if(filesize("{$g['conf_path']}/config.xml") == 0) {
211
		$last_backup = discover_last_backup();
212
		if($last_backup) {
213
			log_error("No config.xml found, attempting last known config restore.");
214
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
215
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
216
		} else {
217
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
218
		}
219
	}
220
	
221
	if($g['booting']) echo ".";
222
	config_lock();
223
	if(!$parse) {
224
		if(file_exists($g['tmp_path'] . '/config.cache')) {
225
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
226
			if(is_null($config)) {
227
				config_unlock();
228
				parse_config(true);
229
			}
230
		} else {
231
			config_unlock();
232
			if(!file_exists($g['conf_path'] . "/config.xml")) {
233
				log_error("No config.xml found, attempting last known config restore.");
234
				file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
235
				$last_backup = discover_last_backup();
236
				if ($last_backup)
237
					restore_backup("/cf/conf/backup/{$last_backup}");
238
				else
239
					log_error("Could not restore config.xml.");
240
			}
241
			$config = parse_config(true);
242
		}
243
	} else {
244
		if(!file_exists($g['conf_path'] . "/config.xml")) {
245
			if($g['booting']) echo ".";
246
			log_error("No config.xml found, attempting last known config restore.");
247
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
248
			$last_backup = discover_last_backup();
249
			if ($last_backup)
250
				restore_backup("/cf/conf/backup/{$last_backup}");
251
			else
252
				log_error("Could not restore config.xml.");
253
		}
254
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
255
		if($config == "-1") {
256
			$last_backup = discover_last_backup();
257
			if ($last_backup)
258
				restore_backup("/cf/conf/backup/{$last_backup}");
259
			else
260
				log_error(gettext("Could not restore config.xml."));
261
		}
262
		generate_config_cache($config);
263
	}
264
	if($g['booting']) echo ".";
265
	alias_make_table($config);
266
	config_unlock();
267

    
268
	/*    override some global configuration parms if they exist
269
	 *    instead of hard coding these checks into the codebase
270
     */
271
	if($config['pptp']['n_pptp_units'])
272
		$g['n_pptp_units'] = $config['pptp']['n_pptp_units'];
273
	if($config['pptp']['pptp_subnet'])
274
		$g['pptp_subnet'] = $config['pptp']['pptp_subnet'];
275

    
276
	if($config['pppoe']['n_pppoe_units'])
277
		$g['n_pppoe_units'] = $config['pppoe']['n_pppoe_units'];
278
	if($config['pppoe']['pppoe_subnet'])
279
		$g['pppoe_subnet'] = $config['pppoe']['pppoe_subnet'];
280

    
281
	return $config;
282
}
283

    
284
/****f* config/generate_config_cache
285
 * NAME
286
 *   generate_config_cache - Write serialized configuration to cache.
287
 * INPUTS
288
 *   $config	- array containing current firewall configuration
289
 * RESULT
290
 *   boolean	- true on completion
291
 ******/
292
function generate_config_cache($config) {
293
	global $g;
294
	config_lock();
295
	conf_mount_rw();
296
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
297
	fwrite($configcache, serialize($config));
298
	fclose($configcache);
299
	conf_mount_ro();
300
	config_unlock();
301
	return true;
302
}
303

    
304
function discover_last_backup() {
305
        $backups = split("\n", `cd /cf/conf/backup && ls -ltr *.xml | awk '{print \$9}'`);
306
		$last_backup = "";
307
        foreach($backups as $backup)
308
        	if($backup)
309
	        	$last_backup = $backup;
310
        return $last_backup;
311
}
312

    
313
function restore_backup($file) {
314
	config_lock();
315
	if(file_exists($file)) {
316
		conf_mount_rw();
317
		copy("$file","/cf/conf/config.xml");
318
		unlink_if_exists("/tmp/config.cache");
319
		log_error("pfSense is restoring the configuration $file");
320
		file_notice("config.xml", "pfSense is restoring the configuration $file", "pfSenseConfigurator", "");
321
		conf_mount_ro();
322
	}
323
	config_unlock();
324
}
325

    
326
/****f* config/parse_config_bootup
327
 * NAME
328
 *   parse_config_bootup - Bootup-specific configuration checks.
329
 * RESULT
330
 *   null
331
 ******/
332
function parse_config_bootup() {
333
	global $config, $g, $noparseconfig;
334
	if($g['booting']) echo ".";
335
	if (!$noparseconfig) {
336
		if (!file_exists("{$g['conf_path']}/config.xml")) {
337
			config_lock();
338
			if ($g['booting']) {
339
				if (strstr($g['platform'], "cdrom")) {
340
					/* try copying the default config. to the floppy */
341
					echo "Resetting factory defaults...\n";
342
					reset_factory_defaults();
343
					if (file_exists("{$g['conf_path']}/config.xml")) {
344
						/* do nothing, we have a file. */
345
					} else {
346
						echo "No XML configuration file found - using factory defaults.\n";
347
						echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
348
						echo "file is inserted. If it isn't, your configuration changes will be lost\n";
349
						echo "on reboot.\n";
350
					}
351
				} else {
352
					$last_backup = discover_last_backup();
353
					if($last_backup) {
354
						log_error("No config.xml found, attempting last known config restore.");
355
						file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
356
						restore_backup("/cf/conf/backup/{$last_backup}");
357
					}
358
					if(!file_exists("{$g['conf_path']}/config.xml")) {
359
						echo "XML configuration file not found.  pfSense cannot continue booting.\n";
360
						mwexec("/sbin/halt");
361
						exit;
362
					}
363
					log_error("Last known config found and restored.  Please double check your configuration file for accuracy.");
364
					file_notice("config.xml", "Last known config found and restored.  Please double check your configuration file for accuracy.", "pfSenseConfigurator", "");
365
				}
366
			} else {
367
				config_unlock();
368
				exit(0);
369
			}
370
		}
371
	}
372

    
373
	if(filesize("{$g['conf_path']}/config.xml") == 0) {
374
		$last_backup = discover_last_backup();
375
		if($last_backup) {
376
			log_error("No config.xml found, attempting last known config restore.");
377
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
378
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
379
		} else {
380
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
381
		}
382
	}
383
	
384
	parse_config(true);
385

    
386
	if ((float)$config['version'] > (float)$g['latest_config']) {
387
		echo <<<EOD
388

    
389

    
390
*******************************************************************************
391
* WARNING!                                                                    *
392
* The current configuration has been created with a newer version of pfSense  *
393
* than this one! This can lead to serious misbehavior and even security       *
394
* holes! You are urged to either upgrade to a newer version of pfSense or     *
395
* revert to the default configuration immediately!                            *
396
*******************************************************************************
397

    
398

    
399
EOD;
400
		}
401

    
402
	/* make alias table (for faster lookups) */
403
	alias_make_table($config);
404
	config_unlock();
405
}
406

    
407
/****f* config/conf_mount_rw
408
 * NAME
409
 *   conf_mount_rw - Mount filesystems read/write.
410
 * RESULT
411
 *   null
412
 ******/
413
/* mount flash card read/write */
414
function conf_mount_rw() {
415
	global $g;
416

    
417
	/* do not mount on cdrom platform */
418
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
419
		return;
420
		
421
	$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
422
	if($status <> 0) {
423
		if($g['booting'])
424
			echo "Disk is dirty.  Running fsck -y\n";
425
		mwexec("/sbin/fsck -y {$g['cf_path']}");
426
		$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
427
	}
428

    
429
	/*    if the platform is soekris or wrap or pfSense, lets mount the
430
	 *    compact flash cards root.
431
         */
432
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx"
433
	   or $g['platform'] == "embedded") {
434
		$status = mwexec("/sbin/mount -u -w /");
435
		/* we could not mount this correctly.  kick off fsck */
436
		if($status <> 0) {
437
			log_error("File system is dirty.  Launching FSCK for /");
438
			mwexec("/sbin/fsck -y /");
439
			$status = mwexec("/sbin/mount -u -w /");
440
		}
441
	}
442
}
443

    
444
/****f* config/conf_mount_ro
445
 * NAME
446
 *   conf_mount_ro - Mount filesystems readonly.
447
 * RESULT
448
 *   null
449
 ******/
450
function conf_mount_ro() {
451
	global $g;
452

    
453
	if($g['booting'] == true)
454
		return;
455

    
456
	/* firmare upgrade in progress */
457
	if(file_exists($g['varrun_path'] . "/fwup.enabled"))
458
		return;
459

    
460
	/* do not umount if generating ssh keys */
461
	if(file_exists("/tmp/keys_generating"))
462
		return;
463

    
464
	/* do not umount on cdrom or pfSense platforms */
465
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
466
		return;
467

    
468
	/* sync data, then force a remount of /cf */
469
	mwexec("/bin/sync");
470
	mwexec("/sbin/mount -u -r -f {$g['cf_path']}");
471
	mwexec("/sbin/mount -u -r -f /");
472
}
473

    
474
/****f* config/convert_config
475
 * NAME
476
 *   convert_config - Attempt to update config.xml.
477
 * DESCRIPTION
478
 *   convert_config() reads the current global configuration
479
 *   and attempts to convert it to conform to the latest
480
 *   config.xml version. This allows major formatting changes
481
 *   to be made with a minimum of breakage.
482
 * RESULT
483
 *   null
484
 ******/
485
/* convert configuration, if necessary */
486
function convert_config() {
487
	global $config, $g;
488

    
489
	if ($config['version'] == $g['latest_config'])
490
		return;		/* already at latest version */
491

    
492
	// Save off config version
493
	$prev_version = $config['version'];
494

    
495
	/* convert 1.0 -> 1.1 */
496
	if ($config['version'] <= 1.0) {
497
		$opti = 1;
498
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
499

    
500
		/* convert DMZ to optional, if necessary */
501
		if (isset($config['interfaces']['dmz'])) {
502

    
503
			$dmzcfg = &$config['interfaces']['dmz'];
504

    
505
			if ($dmzcfg['if']) {
506
				$config['interfaces']['opt' . $opti] = array();
507
				$optcfg = &$config['interfaces']['opt' . $opti];
508

    
509
				$optcfg['enable'] = $dmzcfg['enable'];
510
				$optcfg['descr'] = "DMZ";
511
				$optcfg['if'] = $dmzcfg['if'];
512
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
513
				$optcfg['subnet'] = $dmzcfg['subnet'];
514

    
515
				$ifmap['dmz'] = "opt" . $opti;
516
				$opti++;
517
			}
518

    
519
			unset($config['interfaces']['dmz']);
520
		}
521

    
522
		/* convert WLAN1/2 to optional, if necessary */
523
		for ($i = 1; isset($config['interfaces']['wlan' . $i]); $i++) {
524

    
525
			if (!$config['interfaces']['wlan' . $i]['if']) {
526
				unset($config['interfaces']['wlan' . $i]);
527
				continue;
528
			}
529

    
530
			$wlancfg = &$config['interfaces']['wlan' . $i];
531
			$config['interfaces']['opt' . $opti] = array();
532
			$optcfg = &$config['interfaces']['opt' . $opti];
533

    
534
			$optcfg['enable'] = $wlancfg['enable'];
535
			$optcfg['descr'] = "WLAN" . $i;
536
			$optcfg['if'] = $wlancfg['if'];
537
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
538
			$optcfg['subnet'] = $wlancfg['subnet'];
539
			$optcfg['bridge'] = $wlancfg['bridge'];
540

    
541
			$optcfg['wireless'] = array();
542
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
543
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
544
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
545
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
546

    
547
			$ifmap['wlan' . $i] = "opt" . $opti;
548

    
549
			unset($config['interfaces']['wlan' . $i]);
550
			$opti++;
551
		}
552

    
553
		/* convert filter rules */
554
		$n = count($config['filter']['rule']);
555
		for ($i = 0; $i < $n; $i++) {
556

    
557
			$fr = &$config['filter']['rule'][$i];
558

    
559
			/* remap interface */
560
			if (array_key_exists($fr['interface'], $ifmap))
561
				$fr['interface'] = $ifmap[$fr['interface']];
562
			else {
563
				/* remove the rule */
564
				echo "\nWarning: filter rule removed " .
565
					"(interface '{$fr['interface']}' does not exist anymore).";
566
				unset($config['filter']['rule'][$i]);
567
				continue;
568
			}
569

    
570
			/* remap source network */
571
			if (isset($fr['source']['network'])) {
572
				if (array_key_exists($fr['source']['network'], $ifmap))
573
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
574
				else {
575
					/* remove the rule */
576
					echo "\nWarning: filter rule removed " .
577
						"(source network '{$fr['source']['network']}' does not exist anymore).";
578
					unset($config['filter']['rule'][$i]);
579
					continue;
580
				}
581
			}
582

    
583
			/* remap destination network */
584
			if (isset($fr['destination']['network'])) {
585
				if (array_key_exists($fr['destination']['network'], $ifmap))
586
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
587
				else {
588
					/* remove the rule */
589
					echo "\nWarning: filter rule removed " .
590
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
591
					unset($config['filter']['rule'][$i]);
592
					continue;
593
				}
594
			}
595
		}
596

    
597
		/* convert shaper rules */
598
		$n = count($config['pfqueueing']['rule']);
599
		if (is_array($config['pfqueueing']['rule']))
600
			for ($i = 0; $i < $n; $i++) {
601

    
602
			$fr = &$config['pfqueueing']['rule'][$i];
603

    
604
			/* remap interface */
605
			if (array_key_exists($fr['interface'], $ifmap))
606
				$fr['interface'] = $ifmap[$fr['interface']];
607
			else {
608
				/* remove the rule */
609
				echo "\nWarning: traffic shaper rule removed " .
610
					"(interface '{$fr['interface']}' does not exist anymore).";
611
				unset($config['pfqueueing']['rule'][$i]);
612
				continue;
613
			}
614

    
615
			/* remap source network */
616
			if (isset($fr['source']['network'])) {
617
				if (array_key_exists($fr['source']['network'], $ifmap))
618
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
619
				else {
620
					/* remove the rule */
621
					echo "\nWarning: traffic shaper rule removed " .
622
						"(source network '{$fr['source']['network']}' does not exist anymore).";
623
					unset($config['pfqueueing']['rule'][$i]);
624
					continue;
625
				}
626
			}
627

    
628
			/* remap destination network */
629
			if (isset($fr['destination']['network'])) {
630
				if (array_key_exists($fr['destination']['network'], $ifmap))
631
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
632
				else {
633
					/* remove the rule */
634
					echo "\nWarning: traffic shaper rule removed " .
635
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
636
					unset($config['pfqueueing']['rule'][$i]);
637
					continue;
638
				}
639
			}
640
		}
641

    
642
		$config['version'] = "1.1";
643
	}
644

    
645
	/* convert 1.1 -> 1.2 */
646
	if ($config['version'] <= 1.1) {
647
		/* move LAN DHCP server config */
648
		$tmp = $config['dhcpd'];
649
		$config['dhcpd'] = array();
650
		$config['dhcpd']['lan'] = $tmp;
651

    
652
		/* encrypt password */
653
		$config['system']['password'] = crypt($config['system']['password']);
654

    
655
		$config['version'] = "1.2";
656
	}
657

    
658
	/* convert 1.2 -> 1.3 */
659
	if ($config['version'] <= 1.2) {
660
		/* convert advanced outbound NAT config */
661
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
662
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
663
			$src = $curent['source'];
664
			$curent['source'] = array();
665
			$curent['source']['network'] = $src;
666
			$curent['destination'] = array();
667
			$curent['destination']['any'] = true;
668
		}
669

    
670
		/* add an explicit type="pass" to all filter rules to make things consistent */
671
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
672
			$config['filter']['rule'][$i]['type'] = "pass";
673
		}
674

    
675
		$config['version'] = "1.3";
676
	}
677

    
678
	/* convert 1.3 -> 1.4 */
679
	if ($config['version'] <= 1.3) {
680
		/* convert shaper rules (make pipes) */
681
		if (is_array($config['pfqueueing']['rule'])) {
682
			$config['pfqueueing']['pipe'] = array();
683

    
684
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
685
				$curent = &$config['pfqueueing']['rule'][$i];
686

    
687
				/* make new pipe and associate with this rule */
688
				$newpipe = array();
689
				$newpipe['descr'] = $curent['descr'];
690
				$newpipe['bandwidth'] = $curent['bandwidth'];
691
				$newpipe['delay'] = $curent['delay'];
692
				$newpipe['mask'] = $curent['mask'];
693
				$config['pfqueueing']['pipe'][$i] = $newpipe;
694

    
695
				$curent['targetpipe'] = $i;
696

    
697
				unset($curent['bandwidth']);
698
				unset($curent['delay']);
699
				unset($curent['mask']);
700
			}
701
		}
702

    
703
		$config['version'] = "1.4";
704
	}
705

    
706
	/* Convert 1.4 -> 1.5 */
707
	if ($config['version'] <= 1.4) {
708

    
709
		/* Default route moved */
710
		if (isset($config['interfaces']['wan']['gateway']))
711
			if ($config['interfaces']['wan']['gateway'] <> "")
712
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
713
		unset($config['interfaces']['wan']['gateway']);
714

    
715
                /* Queues are no longer interface specific */
716
                if (isset($config['interfaces']['lan']['schedulertype']))
717
                        unset($config['interfaces']['lan']['schedulertype']);
718
                if (isset($config['interfaces']['wan']['schedulertype']))
719
                        unset($config['interfaces']['wan']['schedulertype']);
720

    
721
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
722
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
723
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
724
                }
725

    
726
		$config['version'] = "1.5";
727
	}
728

    
729
	/* Convert 1.5 -> 1.6 */
730
	if ($config['version'] <= 1.5) {
731
		/* Alternate firmware URL moved */
732
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
733
			$config['system']['alt_firmware_url'] = array();
734
			$config['system']['alt_firmware_url']['enabled'] = "";
735
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
736
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
737
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
738
		} else {
739
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
740
		}
741

    
742
		$config['version'] = "1.6";
743
	}
744

    
745
	/* Convert 1.6 -> 1.7 */
746
	if ($config['version'] <= 1.6) {
747
		/* wipe previous shaper configuration */
748
		unset($config['shaper']['queue']);
749
		unset($config['shaper']['rule']);
750
		unset($config['interfaces']['wan']['bandwidth']);
751
		unset($config['interfaces']['wan']['bandwidthtype']);
752
		unset($config['interfaces']['lan']['bandwidth']);
753
		unset($config['interfaces']['lan']['bandwidthtype']);
754
		$config['shaper']['enable'] = FALSE;
755
		$config['version'] = "1.7";
756
	}
757
	/* Convert 1.7 -> 1.8 */
758
	if ($config['version'] <= 1.7) {
759
		if(isset($config['proxyarp']) && is_array($config['proxyarp']['proxyarpnet'])) {
760
			$proxyarp = &$config['proxyarp']['proxyarpnet'];
761
			foreach($proxyarp as $arpent){
762
				$vip = array();
763
				$vip['mode'] = "proxyarp";
764
				$vip['interface'] = $arpent['interface'];
765
				$vip['descr'] = $arpent['descr'];
766
				if (isset($arpent['range'])) {
767
					$vip['range'] = $arpent['range'];
768
					$vip['type'] = "range";
769
				} else {
770
					$subnet = explode('/', $arpent['network']);
771
					$vip['subnet'] = $subnet[0];
772
					if (isset($subnet[1])) {
773
						$vip['subnet_bits'] = $subnet[1];
774
						$vip['type'] = "network";
775
					} else {
776
						$vip['subnet_bits'] = "32";
777
						$vip['type'] = "single";
778
					}
779
				}
780
				$config['virtualip']['vip'][] = $vip;
781
			}
782
			unset($config['proxyarp']);
783
		}
784
		if(isset($config['installedpackages']) && isset($config['installedpackages']['carp']) && is_array($config['installedpackages']['carp']['config'])) {
785
			$carp = &$config['installedpackages']['carp']['config'];
786
			foreach($carp as $carpent){
787
				$vip = array();
788
				$vip['mode'] = "carp";
789
				$vip['interface'] = "AUTO";
790
				$vip['descr'] = "CARP vhid {$carpent['vhid']}";
791
				$vip['type'] = "single";
792
				$vip['vhid'] = $carpent['vhid'];
793
				$vip['advskew'] = $carpent['advskew'];
794
				$vip['password'] = $carpent['password'];
795
				$vip['subnet'] = $carpent['ipaddress'];
796
				$vip['subnet_bits'] = $carpent['netmask'];
797
				$config['virtualip']['vip'][] = $vip;
798
			}
799
			unset($config['installedpackages']['carp']);
800
		}
801
		/* Server NAT is no longer needed */
802
		unset($config['nat']['servernat']);
803

    
804
		/* enable SSH */
805
		if ($config['version'] == "1.8") {
806
			$config['system']['sshenabled'] = true;
807
		}
808

    
809
		$config['version'] = "1.9";
810
	}
811

    
812
	/* Convert 1.8 -> 1.9 */
813
	if ($config['version'] <= 1.8) {
814
		$config['theme']="metallic";
815
		$config['version'] = "1.9";
816
	}
817
	/* Convert 1.9 -> 2.0 */
818
	if ($config['version'] <= 1.9) {
819
		if(is_array($config['ipsec']['tunnel'])) {
820
			reset($config['ipsec']['tunnel']);
821
			while (list($index, $tunnel) = each($config['ipsec']['tunnel'])) {
822
				/* Sanity check on required variables */
823
				/* This fixes bogus <tunnel> entries - remnant of bug #393 */
824
				if (!isset($tunnel['local-subnet']) && !isset($tunnel['remote-subnet'])) {
825
					unset($config['ipsec']['tunnel'][$tunnel]);
826
				}
827
			}
828
        	}
829
		$config['version'] = "2.0";
830
	}
831
	/* Convert 2.0 -> 2.1 */
832
	if ($config['version'] <= 2.0) {
833
		/* shaper scheduler moved */
834
		if(isset($config['system']['schedulertype'])) {
835
			$config['shaper']['schedulertype'] = $config['system']['schedulertype'];
836
			unset($config['system']['schedulertype']);
837
		}
838
		$config['version'] = "2.1";
839
	}
840
	/* Convert 2.1 -> 2.2 */
841
	if ($config['version'] <= 2.1) {
842
		/* move gateway to wan interface */
843
		$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
844
		$config['version'] = "2.2";
845
	}
846
	/* Convert 2.2 -> 2.3 */
847
	if ($config['version'] <= 2.2) {
848
		if(isset($config['shaper'])) {
849
			/* wipe previous shaper configuration */
850
			unset($config['shaper']);
851
		}
852
		$config['version'] = "2.3";
853
	}
854

    
855
	/* Convert 2.4 -> 2.5 */
856
	if ($config['version'] <= 2.4) {
857
		$config['interfaces']['wan']['use_rrd_gateway'] = $config['system']['use_rrd_gateway'];
858
		unset($config['system']['use_rrd_gateway']);
859
 		$config['version'] = "2.5";
860
	}
861

    
862
	/* Convert 2.5 -> 2.6 */
863
	if ($config['version'] <= 2.5) {
864
		$cron_item = array();
865
		$cron_item['minute'] = "0";
866
		$cron_item['hour'] = "*";
867
		$cron_item['mday'] = "*";
868
		$cron_item['month'] = "*";
869
		$cron_item['wday'] = "*";
870
		$cron_item['who'] = "root";
871
		$cron_item['command'] = "/usr/bin/nice -n20 newsyslog";
872

    
873
		$config['cron']['item'][] = $cron_item;
874

    
875
		$cron_item = array();
876
		$cron_item['minute'] = "1,31";
877
		$cron_item['hour'] = "0-5";
878
		$cron_item['mday'] = "*";
879
		$cron_item['month'] = "*";
880
		$cron_item['wday'] = "*";
881
		$cron_item['who'] = "root";
882
		$cron_item['command'] = "/usr/bin/nice -n20 adjkerntz -a";
883

    
884
		$config['cron']['item'][] = $cron_item;
885

    
886
		$cron_item = array();
887
		$cron_item['minute'] = "1";
888
		$cron_item['hour'] = "*";
889
		$cron_item['mday'] = "1";
890
		$cron_item['month'] = "*";
891
		$cron_item['wday'] = "*";
892
		$cron_item['who'] = "root";
893
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.update_bogons.sh";
894

    
895
		$config['cron']['item'][] = $cron_item;
896

    
897
		$cron_item = array();
898
		$cron_item['minute'] = "*/60";
899
		$cron_item['hour'] = "*";
900
		$cron_item['mday'] = "*";
901
		$cron_item['month'] = "*";
902
		$cron_item['wday'] = "*";
903
		$cron_item['who'] = "root";
904
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 sshlockout";
905

    
906
		$config['cron']['item'][] = $cron_item;
907

    
908
		$cron_item = array();
909
		$cron_item['minute'] = "1";
910
		$cron_item['hour'] = "1";
911
		$cron_item['mday'] = "*";
912
		$cron_item['month'] = "*";
913
		$cron_item['wday'] = "*";
914
		$cron_item['who'] = "root";
915
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.dyndns.update";
916

    
917
		$config['cron']['item'][] = $cron_item;
918

    
919
		$cron_item = array();
920
		$cron_item['minute'] = "*/60";
921
		$cron_item['hour'] = "*";
922
		$cron_item['mday'] = "*";
923
		$cron_item['month'] = "*";
924
		$cron_item['wday'] = "*";
925
		$cron_item['who'] = "root";
926
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 virusprot";
927

    
928
		$config['cron']['item'][] = $cron_item;
929

    
930
		$cron_item = array();
931
		$cron_item['minute'] = "*/60";
932
		$cron_item['hour'] = "*";
933
		$cron_item['mday'] = "*";
934
		$cron_item['month'] = "*";
935
		$cron_item['wday'] = "*";
936
		$cron_item['who'] = "root";
937
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -t 1800 snort2c";
938

    
939
		$config['cron']['item'][] = $cron_item;
940

    
941
		$cron_item = array();
942
		$cron_item['minute'] = "*/5";
943
		$cron_item['hour'] = "*";
944
		$cron_item['mday'] = "*";
945
		$cron_item['month'] = "*";
946
		$cron_item['wday'] = "*";
947
		$cron_item['who'] = "root";
948
		$cron_item['command'] = "/usr/local/bin/checkreload.sh";
949

    
950
		$config['cron']['item'][] = $cron_item;
951

    
952
		/* write crontab entries to file */
953
		configure_cron();
954

    
955
 		$config['version'] = "2.6";
956
	}
957

    
958
	/* Convert 2.6 -> 2.7 */
959
	if ($config['version'] <= 2.6) {
960
		$config['interfaces']['wan']['use_rrd_gateway'] = $config['system']['use_rrd_gateway'];
961
		unset($config['system']['use_rrd_gateway']);
962
		$config['version'] = "2.7";
963
	}
964

    
965
	/* Convert 2.7 -> 2.8 */
966
	if ($config['version'] <= 2.7) {
967
		$founditem = false;
968
		foreach($config['cron']['item'] as $cronitem) {
969
			if($cronitem['command'] == "/usr/local/bin/checkreload.sh")
970
				$founditem = true;
971
		}
972
		if($founditem == false) {
973
			$cron_item = array();
974
			$cron_item['minute'] = "*/5";
975
			$cron_item['hour'] = "*";
976
			$cron_item['mday'] = "*";
977
			$cron_item['month'] = "*";
978
			$cron_item['wday'] = "*";
979
			$cron_item['who'] = "root";
980
			$cron_item['command'] = "/usr/local/bin/checkreload.sh";
981
			$config['cron']['item'][] = $cron_item;
982
		}
983
		$config['version'] = "2.8";
984
	}
985

    
986
	/* Convert 2.8 -> 2.9 */
987
	if ($config['version'] <= 2.8) {
988
		$rule_item = array();
989
		$a_filter = &$config['filter']['rule'];
990
		$rule_item['interface'] = "enc0";
991
		$rule_item['type'] = "pass";
992
		$rule_item['source']['any'] = true;
993
		$rule_item['destination']['any'] = true;
994
		$rule_item['descr'] = "Permit IPSEC traffic.";
995
		$rule_item['statetype'] = "keep state";
996
		$a_filter[] = $rule_item;
997
		$config['version'] = "2.9";
998
	}
999

    
1000
	/* Convert 2.9 -> 4.0 */
1001
	if ($config['version'] <= 3.9) {
1002
		$config['system']['webgui']['auth_method'] = "session";
1003
		$config['system']['webgui']['backing_method'] = "htpasswd";
1004

    
1005
		if (isset ($config['system']['username'])) {
1006
			$config['system']['group'] = array();
1007
			$config['system']['group'][0]['name'] = "admins";
1008
			$config['system']['group'][0]['description'] = "System Administrators";
1009
			$config['system']['group'][0]['scope'] = "system";
1010
			$config['system']['group'][0]['pages'] = "ANY";
1011
			$config['system']['group'][0]['home'] = "index.php";
1012
			$config['system']['group'][0]['gid'] = "110";
1013

    
1014
			$config['system']['user'] = array();
1015
			$config['system']['user'][0]['name'] = "{$config['system']['username']}";
1016
			$config['system']['user'][0]['fullname'] = "System Administrator";
1017
			$config['system']['user'][0]['scope'] = "system";
1018
			$config['system']['user'][0]['groupname'] = "admins";
1019
			$config['system']['user'][0]['password'] = "{$config['system']['password']}";
1020
			$config['system']['user'][0]['uid'] = "0";
1021

    
1022
			$config['system']['user'][0]['priv'] = array();
1023
			$config['system']['user'][0]['priv'][0]['id'] = "lockwc";
1024
			$config['system']['user'][0]['priv'][0]['name'] = "Lock webConfigurator";
1025
			$config['system']['user'][0]['priv'][0]['descr'] = "Indicates whether this user will lock access to the webConfigurator for other users.";
1026
			$config['system']['user'][0]['priv'][1]['id'] = "lock-ipages";
1027
			$config['system']['user'][0]['priv'][1]['name'] = "Lock individual pages";
1028
			$config['system']['user'][0]['priv'][1]['decr'] = "Indicates whether this user will lock individual HTML pages after having accessed a particular page (the lock will be freed if the user leaves or saves the page form).";
1029
			$config['system']['user'][0]['priv'][2]['id'] = "hasshell";
1030
			$config['system']['user'][0]['priv'][2]['name'] = "Has shell access";
1031
			$config['system']['user'][0]['priv'][2]['descr'] = "Indicates whether this user is able to login for example via SSH.";
1032
			$config['system']['user'][0]['priv'][3]['id'] = "copyfiles";
1033
			$config['system']['user'][0]['priv'][3]['name'] = "Is allowed to copy files";
1034
			$config['system']['user'][0]['priv'][3]['descr'] = "Indicates whether this user is allowed to copy files onto the {$g['product_name']} appliance via SCP/SFTP. If you are going to use this privilege, you must install scponly on the appliance (Hint: pkg_add -r scponly).";
1035
			$config['system']['user'][0]['priv'][4]['id'] = "isroot";
1036
			$config['system']['user'][0]['priv'][4]['name'] = "Is root user";
1037
			$config['system']['user'][0]['priv'][4]['descr'] = "This user is associated with the UNIX root user (you should associate this privilege only with one single user).";
1038

    
1039
			$config['system']['nextuid'] = "111";
1040
			$config['system']['nextgid'] = "111";
1041

    
1042
			/* wipe previous auth configuration */
1043
			unset ($config['system']['username']);
1044
			unset ($config['system']['password']);
1045
			
1046
			$config['version'] = "4.0";
1047
		}
1048

    
1049
	}
1050
		
1051
	/* Convert 4.0 -> 4.1 */
1052
	if ($config['version'] <= 4.0) {
1053
		if(!$config['sysctl']) {
1054

    
1055
			$config['sysctl']['item'] = array();
1056
	
1057
			$config['sysctl']['item'][0]['tunable'] = "net.inet.tcp.blackhole";
1058
			$config['sysctl']['item'][0]['desc'] =    "Drop packets to closed TCP ports without returning a RST";
1059
			$config['sysctl']['item'][0]['value'] =   "2";
1060
	
1061
			$config['sysctl']['item'][1]['tunable'] = "net.inet.udp.blackhole";
1062
			$config['sysctl']['item'][1]['desc'] =    "Do not send ICMP port unreachable messages for closed UDP ports";
1063
			$config['sysctl']['item'][1]['value'] =   "1";
1064
	
1065
			$config['sysctl']['item'][2]['tunable'] = "net.inet.ip.random_id";
1066
			$config['sysctl']['item'][2]['desc'] =    "Randomize the ID field in IP packets (default is 0: sequential IP IDs)";
1067
			$config['sysctl']['item'][2]['value'] =   "1";
1068
	
1069
			$config['sysctl']['item'][3]['tunable'] = "net.inet.tcp.drop_synfin";
1070
			$config['sysctl']['item'][3]['desc'] =    "Drop SYN-FIN packets (breaks RFC1379, but nobody uses it anyway)";
1071
			$config['sysctl']['item'][3]['value'] =   "1";
1072
	
1073
			$config['sysctl']['item'][4]['tunable'] = "net.inet.ip.redirect";
1074
			$config['sysctl']['item'][4]['desc'] =    "Disable sending IPv4 redirects";
1075
			$config['sysctl']['item'][4]['value'] =   "0";
1076
	
1077
			$config['sysctl']['item'][5]['tunable'] = "net.inet6.ip6.redirect";
1078
			$config['sysctl']['item'][5]['desc'] =    "Disable sending IPv6 redirects";
1079
			$config['sysctl']['item'][5]['value'] =   "0";
1080
	
1081
			$config['sysctl']['item'][6]['tunable'] = "net.inet.tcp.syncookies";
1082
			$config['sysctl']['item'][6]['desc'] =    "Generate SYN cookies for outbound SYN-ACK packets";
1083
			$config['sysctl']['item'][6]['value'] =   "1";
1084
	
1085
			$config['sysctl']['item'][7]['tunable'] = "net.inet.tcp.recvspace";
1086
			$config['sysctl']['item'][7]['desc'] =    "Maximum incoming TCP datagram size";
1087
			$config['sysctl']['item'][7]['value'] =   "65228";
1088
	
1089
			$config['sysctl']['item'][8]['tunable'] = "net.inet.tcp.sendspace";
1090
			$config['sysctl']['item'][8]['desc'] =    "Maximum outgoing TCP datagram size";
1091
			$config['sysctl']['item'][8]['value'] =   "65228";
1092
	
1093
			$config['sysctl']['item'][9]['tunable'] = "net.inet.ip.fastforwarding";
1094
			$config['sysctl']['item'][9]['desc'] =    "Fastforwarding (see http://lists.freebsd.org/pipermail/freebsd-net/2004-January/002534.html)";
1095
			$config['sysctl']['item'][9]['value'] =   "1";
1096
	
1097
			$config['sysctl']['item'][10]['tunable'] = "net.inet.tcp.delayed_ack";
1098
			$config['sysctl']['item'][10]['desc'] =    "Do not delay ACK to try and piggyback it onto a data packet";
1099
			$config['sysctl']['item'][10]['value'] =   "0";
1100
	
1101
			$config['sysctl']['item'][11]['tunable'] = "net.inet.udp.maxdgram";
1102
			$config['sysctl']['item'][11]['desc'] =    "Maximum outgoing UDP datagram size";
1103
			$config['sysctl']['item'][11]['value'] =   "57344";
1104
	
1105
			$config['sysctl']['item'][12]['tunable'] = "net.link.bridge.pfil_onlyip";
1106
			$config['sysctl']['item'][12]['desc'] =    "Handling of non-IP packets which are not passed to pfil (see if_bridge(4))";
1107
			$config['sysctl']['item'][12]['value'] =   "0";
1108
	
1109
			$config['sysctl']['item'][13]['tunable'] = "net.link.tap.user_open";
1110
			$config['sysctl']['item'][13]['desc'] =    "Allow unprivileged access to tap(4) device nodes";
1111
			$config['sysctl']['item'][13]['value'] =   "1";
1112
	
1113
			$config['sysctl']['item'][14]['tunable'] = "kern.rndtest.verbose";
1114
			$config['sysctl']['item'][14]['desc'] =    "Verbosity of the rndtest driver (0: do not display results on console)";
1115
			$config['sysctl']['item'][14]['value'] =   "0";
1116
	
1117
			$config['sysctl']['item'][15]['tunable'] = "kern.randompid";
1118
			$config['sysctl']['item'][15]['desc'] =    "Randomize PID's (see src/sys/kern/kern_fork.c: sysctl_kern_randompid())";
1119
			$config['sysctl']['item'][15]['value'] =   "347";
1120
	
1121
			$config['sysctl']['item'][16]['tunable'] = "net.inet.tcp.inflight.enable";
1122
			$config['sysctl']['item'][16]['desc'] =    "The system will attempt to calculate the bandwidth delay product for each connection and limit the amount of data queued to the network to just the amount required to maintain optimum throughput. ";
1123
			$config['sysctl']['item'][16]['value'] =   "3";
1124

    
1125
			$config['version'] = "4.1";
1126
		}
1127

    
1128
	}
1129

    
1130
	/* Convert 4.1 -> 4.2 */
1131
	if ($config['version'] <= 4.1) {
1132
		/* enable the rrd config setting by default */
1133
		$config['rrd']['enable'] = true;
1134
		$config['version'] = "4.2";
1135
	}
1136

    
1137
	if ($prev_version != $config['version'])
1138
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
1139
}
1140

    
1141
/****f* config/write_config
1142
 * NAME
1143
 *   write_config - Backup and write the firewall configuration.
1144
 * DESCRIPTION
1145
 *   write_config() handles backing up the current configuration,
1146
 *   applying changes, and regenerating the configuration cache.
1147
 * INPUTS
1148
 *   $desc	- string containing the a description of configuration changes
1149
 *   $backup	- boolean: do not back up current configuration if false.
1150
 * RESULT
1151
 *   null
1152
 ******/
1153
/* save the system configuration */
1154
function write_config($desc="Unknown", $backup = true) {
1155
	global $config, $g;
1156

    
1157
	if($g['bootup']) 
1158
		log_error("WARNING! Configuration written on bootup.  This can cause stray openvpn and load balancing items in config.xml");
1159

    
1160
	if($backup)
1161
		backup_config();
1162

    
1163
	if (time() > mktime(0, 0, 0, 9, 1, 2004))       /* make sure the clock settings are plausible */
1164
		$changetime = time();
1165

    
1166
	/* Log the running script so it's not entirely unlogged what changed */
1167
    if ($desc == "Unknown")
1168
		$desc = "{$_SERVER['SCRIPT_NAME']} made unknown change";
1169

    
1170
	$config['revision']['description'] = $desc;
1171
	$config['revision']['time'] = $changetime;
1172

    
1173
	config_lock();
1174

    
1175
	/* generate configuration XML */
1176
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
1177

    
1178
	conf_mount_rw();
1179

    
1180
	/* write new configuration */
1181
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
1182
	if (!$fd)
1183
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
1184
	fwrite($fd, $xmlconfig);
1185
	fclose($fd);
1186

    
1187
	if($g['platform'] == "embedded") {
1188
		cleanup_backupcache(5);
1189
	} else {
1190
		cleanup_backupcache(30);
1191
	}
1192

    
1193
	if($g['booting'] <> true) {
1194
		conf_mount_ro();
1195
	}
1196

    
1197
	/* re-read configuration */
1198
	$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
1199

    
1200
	/* write config cache */
1201
	$fd = @fopen("{$g['tmp_path']}/config.cache", "wb");
1202
	if ($fd) {
1203
		fwrite($fd, serialize($config));
1204
		fclose($fd);
1205
	}
1206

    
1207
	/* tell kernel to sync fs data */
1208
	mwexec("/bin/sync");
1209

    
1210
	config_unlock();
1211

    
1212
	return $config;
1213
}
1214

    
1215
/****f* config/reset_factory_defaults
1216
 * NAME
1217
 *   reset_factory_defaults - Reset the system to its default configuration.
1218
 * RESULT
1219
 *   integer	- indicates completion
1220
 ******/
1221
function reset_factory_defaults() {
1222
	global $g;
1223

    
1224
	config_lock();
1225
	conf_mount_rw();
1226

    
1227
	/* create conf directory, if necessary */
1228
	safe_mkdir("{$g['cf_conf_path']}");
1229

    
1230
	/* clear out /conf */
1231
	$dh = opendir($g['conf_path']);
1232
	while ($filename = readdir($dh)) {
1233
		if (($filename != ".") && ($filename != "..")) {
1234
			unlink_if_exists($g['conf_path'] . "/" . $filename);
1235
		}
1236
	}
1237
	closedir($dh);
1238

    
1239
	/* copy default configuration */
1240
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
1241

    
1242
	/* call the wizard */
1243
	touch("/conf/trigger_initial_wizard");
1244

    
1245
	conf_mount_ro();
1246
	config_unlock();
1247

    
1248
	return 0;
1249
}
1250

    
1251
function config_restore($conffile) {
1252
	global $config, $g;
1253

    
1254
	if (!file_exists($conffile))
1255
		return 1;
1256

    
1257
    config_lock();
1258
    conf_mount_rw();
1259

    
1260
    backup_config();
1261
    copy($conffile, "{$g['cf_conf_path']}/config.xml");
1262
	$config = parse_config(true);
1263
    write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
1264

    
1265
    conf_mount_ro();
1266
    config_unlock();
1267

    
1268
    return 0;
1269
}
1270

    
1271
function config_install($conffile) {
1272
	global $config, $g;
1273

    
1274
	if (!file_exists($conffile))
1275
		return 1;
1276

    
1277
	if (!config_validate("{$g['conf_path']}/config.xml"))
1278
		return 1;
1279

    
1280
	if($g['booting'] == true)
1281
		echo "Installing configuration...\n";
1282

    
1283
    config_lock();
1284
    conf_mount_rw();
1285

    
1286
    copy($conffile, "{$g['conf_path']}/config.xml");
1287

    
1288
	/* unlink cache file if it exists */
1289
	if(file_exists("{$g['tmp_path']}/config.cache"))
1290
		unlink("{$g['tmp_path']}/config.cache");
1291

    
1292
    conf_mount_ro();
1293
    config_unlock();
1294

    
1295
    return 0;
1296
}
1297

    
1298
function config_validate($conffile) {
1299

    
1300
	global $g, $xmlerr;
1301

    
1302
	$xml_parser = xml_parser_create();
1303

    
1304
	if (!($fp = fopen($conffile, "r"))) {
1305
		$xmlerr = "XML error: unable to open file";
1306
		return false;
1307
	}
1308

    
1309
	while ($data = fread($fp, 4096)) {
1310
		if (!xml_parse($xml_parser, $data, feof($fp))) {
1311
			$xmlerr = sprintf("%s at line %d",
1312
						xml_error_string(xml_get_error_code($xml_parser)),
1313
						xml_get_current_line_number($xml_parser));
1314
			return false;
1315
		}
1316
	}
1317
	xml_parser_free($xml_parser);
1318

    
1319
	fclose($fp);
1320

    
1321
	return true;
1322
}
1323

    
1324
/*   lock configuration file, decide that the lock file
1325
 *   is stale after 10 seconds
1326
 */
1327
function config_lock() {
1328
	global $g, $process_lock;
1329

    
1330
	/* No need to continue if we're the ones holding the lock */
1331
	if ($process_lock)
1332
		return;
1333

    
1334
	$lockfile = "{$g['varrun_path']}/config.lock";
1335

    
1336
	$n = 0;
1337
	while ($n < 10) {
1338
		/* open the lock file in append mode to avoid race condition */
1339
		if ($fd = @fopen($lockfile, "x")) {
1340
			/* succeeded */
1341
			$process_lock = true;
1342
			fclose($fd);
1343
			return;
1344
		} else {
1345
			/* file locked, wait and try again */
1346
			$process_lock = false;
1347
			sleep(1);
1348
			$n++;
1349
		}
1350
	}
1351
}
1352

    
1353
/* unlock configuration file */
1354
function config_unlock() {
1355
	global $g, $process_lock;
1356

    
1357
	$lockfile = "{$g['varrun_path']}/config.lock";
1358
	$process_lock = false;
1359

    
1360
	unlink_if_exists($lockfile);
1361
}
1362

    
1363
function set_networking_interfaces_ports() {
1364
	global $noreboot;
1365
	global $config;
1366
	global $g;
1367
	global $fp;
1368

    
1369
	$fp = fopen('php://stdin', 'r');
1370

    
1371
	$memory = get_memory();
1372
	$avail = $memory[0];
1373

    
1374
	if($avail < 115) {
1375
		echo "\n\n\n";
1376
		echo "DANGER!  WARNING!\n\n";
1377
		echo "pfSense requires *ATLEAST* 128 megs of ram to function correctly.\n";
1378
		echo "Only ($avail) megs of ram has been detected.\n";
1379
		echo "\nPress ENTER to continue.";
1380
		fgets($fp);
1381
		echo "\n";
1382
	}
1383

    
1384
	$iflist = get_interface_list();
1385

    
1386
	echo <<<EOD
1387

    
1388
Valid interfaces are:
1389

    
1390

    
1391
EOD;
1392

    
1393
	if(!is_array($iflist)) {
1394
		echo "No interfaces found!\n";
1395
	} else {
1396
		foreach ($iflist as $iface => $ifa) {
1397
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1398
				$ifa['up'] ? "   (up)" : "");
1399
		}
1400
	}
1401

    
1402
	echo <<<EOD
1403

    
1404
Do you want to set up VLANs first?
1405
If you are not going to use VLANs, or only for optional interfaces, you should
1406
say no here and use the webConfigurator to configure VLANs later, if required.
1407

    
1408
Do you want to set up VLANs now [y|n]?
1409
EOD;
1410

    
1411
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
1412
		vlan_setup();
1413

    
1414
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1415

    
1416
		echo "\n\nVLAN interfaces:\n\n";
1417
		$i = 0;
1418
		foreach ($config['vlans']['vlan'] as $vlan) {
1419

    
1420
			echo sprintf("% -8s%s\n", "vlan{$i}",
1421
				"VLAN tag {$vlan['tag']}, interface {$vlan['if']}");
1422

    
1423
			$iflist['vlan' . $i] = array();
1424
			$i++;
1425
		}
1426
	}
1427

    
1428
	echo <<<EOD
1429

    
1430
*NOTE*  pfSense requires *ATLEAST* 2 assigned interfaces to function.
1431
        If you do not have two interfaces turn off the machine until
1432
	    you do.
1433

    
1434
	    And now in ENGLISH.  If you do not have atleast two *REAL*
1435
	    network interface cards or one nic with multiple VLANS then
1436
	    pfSense *WILL NOT* run correctly.
1437

    
1438
If you do not know the names of your interfaces, you may choose to use
1439
auto-detection... In that case, disconnect all interfaces now before
1440
hitting a.   The system will then prompt you to plug in each nic to
1441
autodetect.
1442

    
1443
EOD;
1444

    
1445
	do {
1446
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
1447
		$lanif = chop(fgets($fp));
1448
		if ($lanif === "") {
1449
			fclose($fp);
1450
			return;
1451
		}
1452

    
1453
		if ($lanif === "a")
1454
			$lanif = autodetect_interface("LAN", $fp);
1455
		else if (!array_key_exists($lanif, $iflist)) {
1456
			echo "\nInvalid interface name '{$lanif}'\n";
1457
			unset($lanif);
1458
			continue;
1459
		}
1460
	} while (!$lanif);
1461

    
1462
	do {
1463
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
1464
		$wanif = chop(fgets($fp));
1465
		if ($wanif === "") {
1466
			return;
1467
		}
1468
		if ($wanif === "a")
1469
			$wanif = autodetect_interface("WAN", $fp);
1470
		else if (!array_key_exists($wanif, $iflist)) {
1471
			echo "\nInvalid interface name '{$wanif}'\n";
1472
			unset($wanif);
1473
			continue;
1474
		}
1475
	} while (!$wanif);
1476

    
1477
	/* optional interfaces */
1478
	$i = 0;
1479
	$optif = array();
1480

    
1481
	while (1) {
1482
		if ($optif[$i])
1483
			$i++;
1484
		$i1 = $i + 1;
1485

    
1486
		if($config['interfaces']['opt' . $i1]['descr'])
1487
			echo "\nOptional interface {$i1} description found: {$config['interfaces']['opt' . $i1]['descr']}";
1488

    
1489
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1490
			"(or nothing if finished): ";
1491

    
1492
		$optif[$i] = chop(fgets($fp));
1493

    
1494
		if ($optif[$i]) {
1495
			if ($optif[$i] === "a") {
1496
				$ad = autodetect_interface("Optional " . $i1, $fp);
1497
				if ($ad)
1498
					$optif[$i] = $ad;
1499
				else
1500
					unset($optif[$i]);
1501
			} else if (!array_key_exists($optif[$i], $iflist)) {
1502
				echo "\nInvalid interface name '{$optif[$i]}'\n";
1503
				unset($optif[$i]);
1504
				continue;
1505
			}
1506
		} else {
1507
			unset($optif[$i]);
1508
			break;
1509
		}
1510
	}
1511

    
1512
	/* check for double assignments */
1513
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1514

    
1515
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1516
		for ($j = ($i+1); $j < count($ifarr); $j++) {
1517
			if ($ifarr[$i] == $ifarr[$j]) {
1518
				echo <<<EOD
1519

    
1520
Error: you cannot assign the same interface name twice!
1521

    
1522
EOD;
1523
				fclose($fp);
1524
				return;
1525
			}
1526
		}
1527
	}
1528

    
1529
	echo <<<EOD
1530

    
1531
The interfaces will be assigned as follows:
1532

    
1533
LAN  -> {$lanif}
1534
WAN  -> {$wanif}
1535

    
1536
EOD;
1537

    
1538
	for ($i = 0; $i < count($optif); $i++) {
1539
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1540
	}
1541

    
1542
echo <<<EOD
1543

    
1544
Do you want to proceed [y|n]?
1545
EOD;
1546

    
1547
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1548

    
1549
		$config['interfaces']['lan']['if'] = $lanif;
1550
		if (preg_match($g['wireless_regex'], $lanif)) {
1551
			if (!is_array($config['interfaces']['lan']['wireless']))
1552
				$config['interfaces']['lan']['wireless'] = array();
1553
		} else {
1554
			unset($config['interfaces']['lan']['wireless']);
1555
		}
1556

    
1557
		$config['interfaces']['wan']['if'] = $wanif;
1558
		if (preg_match($g['wireless_regex'], $wanif)) {
1559
			if (!is_array($config['interfaces']['wan']['wireless']))
1560
				$config['interfaces']['wan']['wireless'] = array();
1561
		} else {
1562
			unset($config['interfaces']['wan']['wireless']);
1563
		}
1564

    
1565
		for ($i = 0; $i < count($optif); $i++) {
1566
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
1567
				$config['interfaces']['opt' . ($i+1)] = array();
1568

    
1569
			$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
1570

    
1571
			/* wireless interface? */
1572
			if (preg_match($g['wireless_regex'], $optif[$i])) {
1573
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
1574
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
1575
			} else {
1576
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
1577
			}
1578

    
1579
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
1580
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
1581
		}
1582

    
1583
		/* remove all other (old) optional interfaces */
1584
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
1585
			unset($config['interfaces']['opt' . ($i+1)]);
1586

    
1587
		write_config();
1588

    
1589
		echo <<<EOD
1590

    
1591

    
1592

    
1593
EOD;
1594

    
1595
		fclose($fp);
1596

    
1597
		if($g['booting'])
1598
			return;
1599

    
1600
		echo "One moment while we reload the settings...";
1601

    
1602
		$g['booting'] = false;
1603

    
1604
		/* resync everything */
1605
		reload_all_sync();
1606

    
1607
		echo " done!\n";
1608

    
1609
		touch("{$g['tmp_path']}/assign_complete");
1610

    
1611
	}
1612
}
1613

    
1614
function autodetect_interface($ifname, $fp) {
1615
	$iflist_prev = get_interface_list("media");
1616
	echo <<<EOD
1617

    
1618
Connect the {$ifname} interface now and make sure that the link is up.
1619
Then press ENTER to continue.
1620

    
1621
EOD;
1622
	fgets($fp);
1623
	$iflist = get_interface_list("media");
1624

    
1625
	foreach ($iflist_prev as $ifn => $ifa) {
1626
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
1627
			echo "Detected link-up on interface {$ifn}.\n";
1628
			return $ifn;
1629
		}
1630
	}
1631

    
1632
	echo "No link-up detected.\n";
1633

    
1634
	return null;
1635
}
1636

    
1637
function vlan_setup() {
1638
	global $iflist, $config, $g, $fp;
1639

    
1640
	$iflist = get_interface_list();
1641

    
1642
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1643

    
1644
	echo <<<EOD
1645

    
1646
WARNING: all existing VLANs will be cleared if you proceed!
1647

    
1648
Do you want to proceed [y|n]?
1649
EOD;
1650

    
1651
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
1652
		return;
1653
	}
1654

    
1655
	$config['vlans']['vlan'] = array();
1656
	echo "\n";
1657

    
1658
	while (1) {
1659
		$vlan = array();
1660

    
1661
		echo "\n\nVLAN Capable interfaces:\n\n";
1662
		if(!is_array($iflist)) {
1663
			echo "No interfaces found!\n";
1664
		} else {
1665
			$vlan_capable=0;
1666
			foreach ($iflist as $iface => $ifa) {
1667
				if (is_jumbo_capable($iface)) {
1668
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1669
						$ifa['up'] ? "   (up)" : "");
1670
					$vlan_capable++;
1671
				}
1672
			}
1673
		}
1674

    
1675
		if($vlan_capable == 0) {
1676
			echo "No VLAN capable interfaces detected.\n";
1677
			return;
1678
		}
1679

    
1680
		echo "\nEnter the parent interface name for the new VLAN (or nothing if finished): ";
1681
		$vlan['if'] = chop(fgets($fp));
1682

    
1683
		if ($vlan['if']) {
1684
			if (!array_key_exists($vlan['if'], $iflist) or
1685
			    !is_jumbo_capable($vlan['if'])) {
1686
				echo "\nInvalid interface name '{$vlan['if']}'\n";
1687
				continue;
1688
			}
1689
		} else {
1690
			break;
1691
		}
1692

    
1693
		echo "Enter the VLAN tag (1-4094): ";
1694
		$vlan['tag'] = chop(fgets($fp));
1695

    
1696
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
1697
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
1698
			continue;
1699
		}
1700

    
1701
		$config['vlans']['vlan'][] = $vlan;
1702
	}
1703
}
1704

    
1705
function system_start_ftp_helpers() {
1706
	require_once("interfaces.inc");
1707
	global $config, $g;
1708

    
1709
	mwexec("/usr/bin/killall ftpsesame");
1710

    
1711
	/* build an array of interfaces to work with */
1712
	$iflist = array("lan" => "lan");
1713
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
1714
		$iflist['opt' . $i] = "opt{$i}";
1715

    
1716
	/* loop through all interfaces and handle pftpx */
1717
	$interface_counter = 0;
1718
	if(isset($config['shaper']['enable'])) {
1719
		if(isset($config['ezshaper']['step5']['p2pcatchall'])) {
1720
			$shaper_queue = "-q qP2PDown ";
1721
		} else { 
1722
			$downq = "q" . convert_friendly_interface_to_friendly_descr($config['ezshaper']['step2']['inside_int']);
1723
			$shaper_queue = "-q {$downq}def ";
1724
		}
1725
	} else {
1726
		$shaper_queue = "";
1727
	}
1728
	foreach ($iflist as $ifent => $ifname) {
1729
		/*    if the ftp proxy is disabled for this interface then kill pftpx
1730
		 *    instance and continue. note that the helpers for port forwards are
1731
		 *    launched in a  different sequence so we are filtering them out
1732
	         *    here by not including -c {$port} -g 8021 first.
1733
		 */
1734
		 /* only install a ftp helper for enabled interfaces. wan and lan are always enabled. */
1735
		if(stristr($ifname, "opt") <> false)
1736
			if(!isset($config['interfaces'][strtolower($ifname)]['enable']))
1737
				continue;
1738
		$port = 8021 + $interface_counter;
1739
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
1740
			/*    item is disabled.  lets ++ the interface counter and
1741
			 *    keep processing interfaces. kill pftpx if already
1742
			 *    running for this instance.
1743
			 */
1744
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/pftpx {$shaper_queue}-c {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
1745
			if($helpers)
1746
				mwexec("/bin/kill {$helpers}");
1747
			$interface_counter++;
1748
		} else {
1749
			/* grab the current interface IP address */
1750
			$int = convert_friendly_interface_to_real_interface_name($ifname);
1751
			$ip = find_interface_ip($int);
1752
			/* are we in routed mode? no source nat rules and not a outside interface? */
1753
			/* If we have advanced outbound nat we skip the FTP proxy, we use ftpsesame */
1754
			if((isset($config['nat']['advancedoutbound']['enable'])) && (! interface_has_gateway($ifname))) {
1755
				$sourcenat = 0;
1756
				/* we are using advanced outbound nat, are we in routing mode? */
1757
				/* if the interface address lies within a outbound NAT source network we should skip */
1758
				if(! empty($config['nat']['advancedoutbound']['rule'])) {
1759
					foreach($config['nat']['advancedoutbound']['rule'] as $natnetwork) {
1760
						if(ip_in_subnet($ip, $natnetwork['source']['network'])) {
1761
							/* if the interface address is matched in the AON Rule we need the ftp proxy */
1762
							$sourcenat++;
1763
						}
1764
					}
1765
				}
1766
				if($sourcenat == 0) {
1767
					if($g['debug'])
1768
						log_error("Config: No AON rule matched for interface {$ifname} - not using FTP proxy");
1769
					mwexec("/usr/local/sbin/ftpsesame -i $int");
1770
					$interface_counter++;
1771
					continue;
1772
				} else {
1773
					if($g['debug'])
1774
						log_error("Config: AON rule matched for interface {$ifname} - using FTP proxy");
1775
				}
1776
			}
1777
			/* if pftpx is already running then do not launch it again */
1778
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/pftpx {$shaper_queue}-c {$port}\" | grep -v grep | sed \"s/  */ /g\"");
1779
			if(!$helpers && $ip)
1780
 				mwexec("/usr/local/sbin/pftpx {$shaper_queue}-c {$port} -g 8021 {$ip}");
1781
			if(!$ip)
1782
				mwexec("/usr/local/sbin/ftpsesame {$shaper_queue}-i $int");
1783
			$interface_counter++;
1784
		}
1785
	}
1786
	/* support bridged interfaces.  even they need ftp mojo */
1787
	$num_bridges = find_number_of_created_bridges();
1788
	$num_bridges++;
1789
	for($x=0; $x<$num_bridges; $x++) {
1790
		mwexec("/usr/local/sbin/ftpsesame {$shaper_queue}-i bridge{$x}");
1791
	}
1792
}
1793

    
1794
function cleanup_backupcache($revisions = 30) {
1795
	global $g;
1796
	$i = false;
1797
	config_lock();
1798
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1799
		conf_mount_rw();
1800
		$backups = get_backups();
1801
		$newbaks = array();
1802
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
1803
		$baktimes = $backups['versions'];
1804
		$tocache = array();
1805
		unset($backups['versions']);
1806
   		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
1807
   			if(filesize($backup) == 0) {
1808
   				unlink($backup);
1809
   				continue;
1810
   			}
1811
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
1812
            if(!in_array($tocheck, $baktimes)) {
1813
				$i = true;
1814
				if($g['booting'])
1815
					print " " . $tocheck . "a";
1816
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
1817
				if($newxml == "-1") {
1818
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
1819
					unlink($backup);
1820
					continue;
1821
				}
1822
				if($newxml['revision']['description'] == "")
1823
					$newxml['revision']['description'] = "Unknown";
1824
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
1825
			}
1826
    	}
1827
		foreach($backups as $checkbak) {
1828

    
1829
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
1830
				$newbaks[] = $checkbak;
1831
			} else {
1832
				$i = true;
1833
				if($g['booting']) print " " . $tocheck . "r";
1834
			}
1835
		}
1836
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
1837
		if(is_int($revisions) and (count($tocache) > $revisions)) {
1838
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
1839
			foreach($toslice as $sliced)
1840
				$newcache[$sliced] = $tocache[$sliced];
1841
			foreach($tocache as $version => $versioninfo) {
1842
				if(!in_array($version, array_keys($newcache))) {
1843
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
1844
					if($g['booting']) print " " . $tocheck . "d";
1845
				}
1846
			}
1847
			$tocache = $newcache;
1848
		}
1849
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1850
        fwrite($bakout, serialize($tocache));
1851
		fclose($bakout);
1852
		conf_mount_ro();
1853
	}
1854
	if($g['booting']) {
1855
		if($i) {
1856
			print "done.\n";
1857
		}
1858
	}
1859
	config_unlock();
1860
}
1861

    
1862
function get_backups() {
1863
	global $g;
1864
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1865
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1866
		$bakvers = array_keys($confvers);
1867
		$toreturn = array();
1868
		sort($bakvers);
1869
		// 	$bakvers = array_reverse($bakvers);
1870
		foreach(array_reverse($bakvers) as $bakver)
1871
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
1872
	} else {
1873
		return false;
1874
	}
1875
	$toreturn['versions'] = $bakvers;
1876
	return $toreturn;
1877
}
1878

    
1879
function backup_config() {
1880
	global $config, $g;
1881

    
1882
	if($g['platform'] == "cdrom")
1883
		return;
1884

    
1885
	conf_mount_rw();
1886

    
1887
	/* Create backup directory if needed */
1888
	safe_mkdir("{$g['cf_conf_path']}/backup");
1889

    
1890
    if($config['revision']['time'] == "") {
1891
            $baktime = 0;
1892
    } else {
1893
            $baktime = $config['revision']['time'];
1894
    }
1895
    if($config['revision']['description'] == "") {
1896
            $bakdesc = "Unknown";
1897
    } else {
1898
            $bakdesc = $config['revision']['description'];
1899
    }
1900
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
1901
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1902
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1903
    } else {
1904
            $backupcache = array();
1905
    }
1906
    $backupcache[$baktime] = array('description' => $bakdesc);
1907
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1908
    fwrite($bakout, serialize($backupcache));
1909
    fclose($bakout);
1910

    
1911
	conf_mount_ro();
1912

    
1913
	return true;
1914
}
1915

    
1916
function mute_kernel_msgs() {
1917
	exec("/sbin/conscontrol mute on");
1918
}
1919

    
1920
function unmute_kernel_msgs() {
1921
	exec("/sbin/conscontrol mute off");
1922
}
1923

    
1924
function start_devd() {
1925
	exec("/sbin/devd");
1926
	sleep(1);
1927
	if(file_exists("/tmp/rc.linkup"))
1928
		unlink("/tmp/rc.linkup");
1929
}
1930

    
1931
function is_interface_mismatch() {
1932
	global $config, $g;
1933
	$lan_if = $config['interfaces']['lan']['if'];
1934
	$wan_if = get_real_wan_interface();
1935
	$do_assign = 0;
1936
	/* we need to ignore the vlan interface checks) */
1937
	if (stristr($lan_if, "vlan") == false and stristr($wan_if, "vlan") == false) {
1938
		if (does_interface_exist($lan_if) == false)
1939
			$do_assign = 1;
1940
		if ($config['interfaces']['wan']['ipaddr'] <> "pppoe" && $config['interfaces']['wan']['ipaddr'] <> "pptp" && $do_assign == 0)
1941
			if (does_interface_exist($wan_if) == false)
1942
				$do_assign = 1;
1943
	}
1944
	/* XXX: enumerate OPT interfaces looking for mismatches */
1945
	if (file_exists("{$g['tmp_path']}/assign_complete"))
1946
		return false;
1947
	if ($do_assign == 1)
1948
		return true;
1949
	else
1950
		return false;
1951
}
1952

    
1953
function set_device_perms() {
1954
	$devices = array(
1955
		'pf'	=> array(	'user'	=> 'proxy',
1956
					'group'	=> 'proxy',
1957
					'mode'	=> 0660),
1958
		);
1959

    
1960
	foreach ($devices as $name => $attr) {
1961
		$path = "/dev/$name";
1962
		if (file_exists($path)) {
1963
			chown($path, $attr['user']);
1964
			chgrp($path, $attr['group']);
1965
			chmod($path, $attr['mode']);
1966
		}
1967
	}
1968
}
1969

    
1970
if($g['booting']) echo ".";
1971
$config = parse_config();
1972

    
1973
?>
(6-6/29)