Project

General

Profile

Download (25 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	config.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	All rights reserved.
7

    
8
	originally part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

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

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

    
34
/* include globals/utility/XML parser files */
35
require_once("globals.inc");
36
require_once("util.inc");
37
require_once("pfsense-utils.inc");
38
require_once("xmlparse.inc");
39

    
40
/* read platform */
41
if (file_exists("{$g['etc_path']}/platform")) {
42
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
43
} else {
44
	$g['platform'] = "unknown";
45
}
46

    
47
/* if our config file exists bail out, we're already set. */
48
if ($g['booting'] and !file_exists($g['cf_conf_path'] . "/config.xml")  ) {
49
	/* find the device where config.xml resides and write out an fstab */
50
	unset($cfgdevice);
51

    
52
	/* check if there's already an fstab (NFS booting?) */
53
	if (!file_exists("{$g['etc_path']}/fstab")) {
54

    
55
		if (strstr($g['platform'], "cdrom")) {
56
			/* config is on floppy disk for CD-ROM version */
57
			$cfgdevice = $cfgpartition = "fd0";
58
			$cfgfstype = "msdos";
59
		} else {
60
			/* probe kernel known disks until we find one with config.xml */
61
			$disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
62
			foreach ($disks as $mountdisk) {
63
				/* skip mfs mounted filesystems */
64
				if (strstr($mountdisk, "md"))
65
					continue;
66
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
67
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
68
						/* found it */
69
						$cfgdevice = $mountdisk;
70
						$cfgpartition = $cfgdevice . "a";
71
						$cfgfstype = "ufs";
72
						echo "Found configuration on $cfgdevice.\n";
73
					}
74

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

    
77
					if ($cfgdevice)
78
						break;
79
				}
80
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}d {$g['cf_path']}") == 0) {
81
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
82
						/* found it */
83
						$cfgdevice = $mountdisk;
84
						$cfgpartition = $cfgdevice . "d";
85
						$cfgfstype = "ufs";
86
						echo "Found configuration on $cfgdevice.\n";
87
					}
88

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

    
91
					if ($cfgdevice)
92
						break;
93
				}
94
			}
95
		}
96

    
97
		if (!$cfgdevice) {
98
			/* no device found, print an error and die */
99
			echo <<<EOD
100

    
101

    
102
*******************************************************************************
103
* FATAL ERROR                                                                 *
104
* The device that contains the configuration file (config.xml) could not be   *
105
* found. pfSense cannot continue booting.                                     *
106
*******************************************************************************
107

    
108

    
109
EOD;
110

    
111
			mwexec("/sbin/halt");
112
			exit;
113
		}
114

    
115
		/* write device name to a file for rc.firmware */
116
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
117
		fwrite($fd, $cfgdevice . "\n");
118
		fclose($fd);
119

    
120
		/* write out an fstab */
121
		$fd = fopen("{$g['etc_path']}/fstab", "w");
122

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

    
126
		fwrite($fd, $fstab);
127
		fclose($fd);
128
	}
129

    
130
	/* mount all filesystems */
131
	mwexec("/sbin/mount -a");
132
}
133

    
134
/* parse configuration */
135
if (!$noparseconfig) {
136

    
137
	config_lock();
138

    
139
	/* see if there's a newer cache file */
140
	if (file_exists("{$g['tmp_path']}/config.cache") &&
141
		(filemtime("{$g['tmp_path']}/config.cache") >=
142
		 filemtime("{$g['conf_path']}/config.xml"))) {
143

    
144
		/* read cache */
145
		$config = unserialize(file_get_contents("{$g['tmp_path']}/config.cache"));
146

    
147
	} else {
148

    
149
		if (!file_exists("{$g['conf_path']}/config.xml")) {
150
			if ($g['booting']) {
151
				if (strstr($g['platform'], "cdrom")) {
152
					/* try copying the default config. to the floppy */
153
					reset_factory_defaults();
154

    
155
					echo "No XML configuration file found - using factory defaults.\n";
156
					echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
157
					echo "file is inserted. If it isn't, your configuration changes will be lost\n";
158
					echo "on reboot.\n";
159
				} else {
160
					echo "XML configuration file not found.  pfSense cannot continue booting.\n";
161
					mwexec("/sbin/halt");
162
					exit;
163
				}
164
			} else {
165
				config_unlock();
166
				exit(0);
167
			}
168
		}
169

    
170
		$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
171

    
172
		if ((float)$config['version'] > (float)$g['latest_config']) {
173
			if ($g['booting']) {
174
				echo <<<EOD
175

    
176

    
177
*******************************************************************************
178
* WARNING!                                                                    *
179
* The current configuration has been created with a newer version of pfSense  *
180
* than this one! This can lead to serious misbehavior and even security       *
181
* holes! You are urged to either upgrade to a newer version of pfSense or     *
182
* revert to the default configuration immediately!                            *
183
*******************************************************************************
184

    
185

    
186
EOD;
187
			}
188
		}
189

    
190
		/* write config cache */
191
		$fd = @fopen("{$g['tmp_path']}/config.cache", "wb");
192
		if ($fd) {
193
			fwrite($fd, serialize($config));
194
			fclose($fd);
195
		}
196
	}
197

    
198
	config_unlock();
199

    
200
	/* make alias table (for faster lookups) */
201
	alias_make_table();
202
}
203

    
204
/* mount flash card read/write */
205
function conf_mount_rw() {
206
	global $g;
207

    
208
	/* don't use mount -u anymore
209
	   (doesn't sync the files properly and /bin/sync won't help either) */
210
	mwexec("/sbin/umount -f {$g['cf_path']}");
211
	mwexec("/sbin/mount -w -o noatime {$g['cf_path']}");
212
	/* if the platform is soekris or wrap, lets mount the
213
	   compact flash card. */
214
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx") {
215
		mwexec("/sbin/umount -f {$g['embeddedbootupslice']}");
216
		mwexec("/sbin/mount -w {$g['embeddedbootupslice']}");
217
	}
218
}
219

    
220
/* mount flash card read only */
221
function conf_mount_ro() {
222
	global $g;
223

    
224
	mwexec("/sbin/umount -f {$g['cf_path']}");
225
	mwexec("/sbin/mount -r {$g['cf_path']}");
226
	/* if the platform is soekris or wrap, lets unmount the
227
	   compact flash card. */
228
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx") {
229
		mwexec("/sbin/umount -f {$g['embeddedbootupslice']}");
230
		mwexec("/sbin/mount -r {$g['embeddedbootupslice']}");
231
	}
232
}
233

    
234
/* convert configuration, if necessary */
235
function convert_config() {
236
	global $config, $pkg_config, $g;
237

    
238
	if ($config['version'] == $g['latest_config'])
239
		return;		/* already at latest version */
240

    
241
	if ($g['booting'])
242
		echo "Converting configuration... ";
243

    
244
	// Save off config version
245
	$prev_version = $config['version'];
246

    
247
	/* convert 1.0 -> 1.1 */
248
	if ($config['version'] == "1.0") {
249
		$opti = 1;
250
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
251

    
252
		/* convert DMZ to optional, if necessary */
253
		if (isset($config['interfaces']['dmz'])) {
254

    
255
			$dmzcfg = &$config['interfaces']['dmz'];
256

    
257
			if ($dmzcfg['if']) {
258
				$config['interfaces']['opt' . $opti] = array();
259
				$optcfg = &$config['interfaces']['opt' . $opti];
260

    
261
				$optcfg['enable'] = $dmzcfg['enable'];
262
				$optcfg['descr'] = "DMZ";
263
				$optcfg['if'] = $dmzcfg['if'];
264
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
265
				$optcfg['subnet'] = $dmzcfg['subnet'];
266

    
267
				$ifmap['dmz'] = "opt" . $opti;
268
				$opti++;
269
			}
270

    
271
			unset($config['interfaces']['dmz']);
272
		}
273

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

    
277
			if (!$config['interfaces']['wlan' . $i]['if']) {
278
				unset($config['interfaces']['wlan' . $i]);
279
				continue;
280
			}
281

    
282
			$wlancfg = &$config['interfaces']['wlan' . $i];
283
			$config['interfaces']['opt' . $opti] = array();
284
			$optcfg = &$config['interfaces']['opt' . $opti];
285

    
286
			$optcfg['enable'] = $wlancfg['enable'];
287
			$optcfg['descr'] = "WLAN" . $i;
288
			$optcfg['if'] = $wlancfg['if'];
289
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
290
			$optcfg['subnet'] = $wlancfg['subnet'];
291
			$optcfg['bridge'] = $wlancfg['bridge'];
292

    
293
			$optcfg['wireless'] = array();
294
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
295
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
296
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
297
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
298

    
299
			$ifmap['wlan' . $i] = "opt" . $opti;
300

    
301
			unset($config['interfaces']['wlan' . $i]);
302
			$opti++;
303
		}
304

    
305
		/* convert filter rules */
306
		$n = count($config['filter']['rule']);
307
		for ($i = 0; $i < $n; $i++) {
308

    
309
			$fr = &$config['filter']['rule'][$i];
310

    
311
			/* remap interface */
312
			if (array_key_exists($fr['interface'], $ifmap))
313
				$fr['interface'] = $ifmap[$fr['interface']];
314
			else {
315
				/* remove the rule */
316
				echo "\nWarning: filter rule removed " .
317
					"(interface '{$fr['interface']}' does not exist anymore).";
318
				unset($config['filter']['rule'][$i]);
319
				continue;
320
			}
321

    
322
			/* remap source network */
323
			if (isset($fr['source']['network'])) {
324
				if (array_key_exists($fr['source']['network'], $ifmap))
325
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
326
				else {
327
					/* remove the rule */
328
					echo "\nWarning: filter rule removed " .
329
						"(source network '{$fr['source']['network']}' does not exist anymore).";
330
					unset($config['filter']['rule'][$i]);
331
					continue;
332
				}
333
			}
334

    
335
			/* remap destination network */
336
			if (isset($fr['destination']['network'])) {
337
				if (array_key_exists($fr['destination']['network'], $ifmap))
338
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
339
				else {
340
					/* remove the rule */
341
					echo "\nWarning: filter rule removed " .
342
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
343
					unset($config['filter']['rule'][$i]);
344
					continue;
345
				}
346
			}
347
		}
348

    
349
		/* convert shaper rules */
350
		$n = count($config['pfqueueing']['rule']);
351
		if (is_array($config['pfqueueing']['rule']))
352
			for ($i = 0; $i < $n; $i++) {
353

    
354
			$fr = &$config['pfqueueing']['rule'][$i];
355

    
356
			/* remap interface */
357
			if (array_key_exists($fr['interface'], $ifmap))
358
				$fr['interface'] = $ifmap[$fr['interface']];
359
			else {
360
				/* remove the rule */
361
				echo "\nWarning: traffic shaper rule removed " .
362
					"(interface '{$fr['interface']}' does not exist anymore).";
363
				unset($config['pfqueueing']['rule'][$i]);
364
				continue;
365
			}
366

    
367
			/* remap source network */
368
			if (isset($fr['source']['network'])) {
369
				if (array_key_exists($fr['source']['network'], $ifmap))
370
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
371
				else {
372
					/* remove the rule */
373
					echo "\nWarning: traffic shaper rule removed " .
374
						"(source network '{$fr['source']['network']}' does not exist anymore).";
375
					unset($config['pfqueueing']['rule'][$i]);
376
					continue;
377
				}
378
			}
379

    
380
			/* remap destination network */
381
			if (isset($fr['destination']['network'])) {
382
				if (array_key_exists($fr['destination']['network'], $ifmap))
383
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
384
				else {
385
					/* remove the rule */
386
					echo "\nWarning: traffic shaper rule removed " .
387
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
388
					unset($config['pfqueueing']['rule'][$i]);
389
					continue;
390
				}
391
			}
392
		}
393

    
394
		$config['version'] = "1.1";
395
	}
396

    
397
	/* convert 1.1 -> 1.2 */
398
	if ($config['version'] == "1.1") {
399
		/* move LAN DHCP server config */
400
		$tmp = $config['dhcpd'];
401
		$config['dhcpd'] = array();
402
		$config['dhcpd']['lan'] = $tmp;
403

    
404
		/* encrypt password */
405
		$config['system']['password'] = crypt($config['system']['password']);
406

    
407
		$config['version'] = "1.2";
408
	}
409

    
410
	/* convert 1.2 -> 1.3 */
411
	if ($config['version'] == "1.2") {
412
		/* convert advanced outbound NAT config */
413
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
414
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
415
			$src = $curent['source'];
416
			$curent['source'] = array();
417
			$curent['source']['network'] = $src;
418
			$curent['destination'] = array();
419
			$curent['destination']['any'] = true;
420
		}
421

    
422
		/* add an explicit type="pass" to all filter rules to make things consistent */
423
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
424
			$config['filter']['rule'][$i]['type'] = "pass";
425
		}
426

    
427
		$config['version'] = "1.3";
428
	}
429

    
430
	/* convert 1.3 -> 1.4 */
431
	if ($config['version'] == "1.3") {
432
		/* convert shaper rules (make pipes) */
433
		if (is_array($config['pfqueueing']['rule'])) {
434
			$config['pfqueueing']['pipe'] = array();
435

    
436
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
437
				$curent = &$config['pfqueueing']['rule'][$i];
438

    
439
				/* make new pipe and associate with this rule */
440
				$newpipe = array();
441
				$newpipe['descr'] = $curent['descr'];
442
				$newpipe['bandwidth'] = $curent['bandwidth'];
443
				$newpipe['delay'] = $curent['delay'];
444
				$newpipe['mask'] = $curent['mask'];
445
				$config['pfqueueing']['pipe'][$i] = $newpipe;
446

    
447
				$curent['targetpipe'] = $i;
448

    
449
				unset($curent['bandwidth']);
450
				unset($curent['delay']);
451
				unset($curent['mask']);
452
			}
453
		}
454

    
455
		$config['version'] = "1.4";
456
	}
457

    
458
	/* Convert 1.4 -> 1.5 */
459
	if ($config['version'] == "1.4") {
460

    
461
		/* Default route moved */
462
		if (isset($config['interfaces']['wan']['gateway']))
463
			if ($config['interfaces']['wan']['gateway'] <> "")
464
				$config['system']['gateway'] = $config['interfaces']['wan']['gateway'];
465
		unset($config['interfaces']['wan']['gateway']);
466

    
467
                /* Queues are no longer interface specific */
468
                if (isset($config['interfaces']['lan']['schedulertype']))
469
                        unset($config['interfaces']['lan']['schedulertype']);
470
                if (isset($config['interfaces']['wan']['schedulertype']))
471
                        unset($config['interfaces']['wan']['schedulertype']);
472

    
473
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
474
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
475
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
476
                }
477

    
478
		$config['version'] = "1.5";
479
	}
480

    
481
	/* Convert 1.5 -> 1.6 */
482
	if ($config['version'] == "1.5") {
483
		/* Alternate firmware URL moved */
484
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
485
			$config['system']['alt_firmware_url'] = array();
486
			$config['system']['alt_firmware_url']['enabled'] = "";
487
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
488
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
489
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
490
		} else {
491
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
492
		}
493

    
494
		$config['version'] = "1.6";
495
	}
496

    
497
	if ($prev_version != $config['version'])
498
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
499

    
500
	if ($g['booting'])
501
		echo "Done\n";
502
}
503

    
504
/* save the system configuration */
505
function write_config($desc="Non-described system change") {
506

    
507
	global $config, $g;
508
	$lastchange = $config['lastchange'];
509

    
510
	config_lock();
511

    
512
	conf_mount_rw();
513

    
514
	if (time() > mktime(0, 0, 0, 9, 1, 2004))	/* make sure the clock settings is plausible */
515
		$config['lastchange'] = time();
516

    
517
	$config['lastchangedesc'] = $desc;
518

    
519
	/* generate configuration XML */
520
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
521

    
522
	/* archive off old config */
523
	/* XXX: billm beginning of version control functionality
524
	 * needs it's own directory, a front end, a way to prompt for change comments, and much more
525
	 * really just stubbing this in, not for use!
526
	 */
527
	if (isset($config['system']['version_control'])) {
528
		$fd = fopen("{$g['cf_conf_path']}/bak/config-{$lastchange}.xml", "w");
529
		if (!$fd)
530
			die("Unable to open {$g['cf_conf_path']}/bak/config-{$config['lastchange']}.xml for writing in write_config()\n");
531
		fwrite($fd, $xmlconfig);
532
		fclose($fd);
533
	}
534

    
535
	/* write configuration */
536
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
537

    
538
	if (!$fd)
539
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
540

    
541
	fwrite($fd, $xmlconfig);
542
	fclose($fd);
543

    
544
	conf_mount_ro();
545

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

    
549
	/* write config cache */
550
	$fd = @fopen("{$g['tmp_path']}/config.cache", "wb");
551
	if ($fd) {
552
		fwrite($fd, serialize($config));
553
		fclose($fd);
554
	}
555

    
556
	config_unlock();
557
}
558

    
559
function reset_factory_defaults() {
560

    
561
	global $g;
562

    
563
	config_lock();
564

    
565
	conf_mount_rw();
566

    
567
	/* create conf directory, if necessary */
568
	if (!file_exists("{$g['cf_conf_path']}"))
569
		@mkdir("{$g['cf_conf_path']}");
570

    
571
	/* clear out /conf */
572
	$dh = opendir($g['conf_path']);
573
	while ($filename = readdir($dh)) {
574
		if (($filename != ".") && ($filename != "..")) {
575
			unlink($g['conf_path'] . "/" . $filename);
576
		}
577
	}
578
	closedir($dh);
579

    
580
	/* copy default configuration */
581
	@copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
582

    
583
	conf_mount_ro();
584

    
585
	config_unlock();
586

    
587
	return 0;
588
}
589

    
590
function config_install($conffile) {
591

    
592
	global $config, $g;
593

    
594
	if (!file_exists($conffile))
595
		return 1;
596

    
597
	config_lock();
598
	conf_mount_rw();
599

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

    
602
	conf_mount_ro();
603
	config_unlock();
604

    
605
	return 0;
606
}
607

    
608
/* lock configuration file, decide that the lock file is stale after
609
   10 seconds */
610
function config_lock() {
611

    
612
	global $g;
613

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

    
616
	$n = 0;
617
	while ($n < 10) {
618
		/* open the lock file in append mode to avoid race condition */
619
		if ($fd = @fopen($lockfile, "x")) {
620
			/* succeeded */
621
			fclose($fd);
622
			return;
623
		} else {
624
			/* file locked, wait and try again */
625
			sleep(1);
626
			$n++;
627
		}
628
	}
629
}
630

    
631
/* unlock configuration file */
632
function config_unlock() {
633

    
634
	global $g;
635

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

    
638
	if (file_exists($lockfile))
639
		unlink($lockfile);
640
}
641

    
642
function set_networking_interfaces_ports() {
643
	global $noreboot;
644
	global $config;
645
	global $g;
646
	global $fp;
647

    
648
	$fp = fopen('php://stdin', 'r');
649

    
650
	$iflist = get_interface_list();
651

    
652
	echo <<<EOD
653

    
654
Valid interfaces are:
655

    
656

    
657
EOD;
658

    
659
	foreach ($iflist as $iface => $ifa) {
660
		echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
661
			$ifa['up'] ? "   (up)" : "");
662
	}
663

    
664
	echo <<<EOD
665

    
666
Do you want to set up VLANs first?
667
If you are not going to use VLANs, or only for optional interfaces, you
668
should say no here and use the webGUI to configure VLANs later, if required.
669

    
670
Do you want to set up VLANs now [y|n]?
671
EOD;
672

    
673
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
674
		vlan_setup();
675

    
676
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
677

    
678
		echo "\n\nVLAN interfaces:\n\n";
679
		$i = 0;
680
		foreach ($config['vlans']['vlan'] as $vlan) {
681

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

    
685
			$iflist['vlan' . $i] = array();
686
			$i++;
687
		}
688
	}
689

    
690
	echo <<<EOD
691

    
692
If you do not know the names of your interfaces, you may choose to use
693
auto-detection. In that case, disconnect all interfaces before you begin,
694
and reconnect each one when prompted to do so.
695

    
696
EOD;
697

    
698
	do {
699
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
700
		$lanif = chop(fgets($fp));
701
		if ($lanif === "") {
702
			exit(0);
703
		}
704

    
705
		if ($lanif === "a")
706
			$lanif = autodetect_interface("LAN", $fp);
707
		else if (!array_key_exists($lanif, $iflist)) {
708
			echo "\nInvalid interface name '{$lanif}'\n";
709
			unset($lanif);
710
			continue;
711
		}
712
	} while (!$lanif);
713

    
714
	do {
715
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
716
		$wanif = chop(fgets($fp));
717
		if ($wanif === "") {
718
			exit(0);
719
		}
720
		if ($wanif === "a")
721
			$wanif = autodetect_interface("WAN", $fp);
722
		else if (!array_key_exists($wanif, $iflist)) {
723
			echo "\nInvalid interface name '{$wanif}'\n";
724
			unset($wanif);
725
			continue;
726
		}
727
	} while (!$wanif);
728

    
729
	/* optional interfaces */
730
	$i = 0;
731
	$optif = array();
732

    
733
	while (1) {
734
		if ($optif[$i])
735
			$i++;
736
		$i1 = $i + 1;
737
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
738
			"(or nothing if finished): ";
739
		$optif[$i] = chop(fgets($fp));
740

    
741
		if ($optif[$i]) {
742
			if ($optif[$i] === "a") {
743
				$ad = autodetect_interface("Optional " . $i1, $fp);
744
				if ($ad)
745
					$optif[$i] = $ad;
746
				else
747
					unset($optif[$i]);
748
			} else if (!array_key_exists($optif[$i], $iflist)) {
749
				echo "\nInvalid interface name '{$optif[$i]}'\n";
750
				unset($optif[$i]);
751
				continue;
752
			}
753
		} else {
754
			unset($optif[$i]);
755
			break;
756
		}
757
	}
758

    
759
	/* check for double assignments */
760
	$ifarr = array_merge(array($lanif, $wanif), $optif);
761

    
762
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
763
		for ($j = ($i+1); $j < count($ifarr); $j++) {
764
			if ($ifarr[$i] == $ifarr[$j]) {
765
				echo <<<EOD
766

    
767
Error: you cannot assign the same interface name twice!
768

    
769
EOD;
770

    
771
				exit(0);
772
			}
773
		}
774
	}
775

    
776
	echo <<<EOD
777

    
778
The interfaces will be assigned as follows:
779

    
780
LAN  -> {$lanif}
781
WAN  -> {$wanif}
782

    
783
EOD;
784

    
785
	for ($i = 0; $i < count($optif); $i++) {
786
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
787
	}
788

    
789
	if(!$noreboot) echo "\npfSense will reboot after saving the changes.\n";
790

    
791
echo <<<EOD
792

    
793
Do you want to proceed [y|n]?
794
EOD;
795

    
796
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
797

    
798
		$config['interfaces']['lan']['if'] = $lanif;
799
		if (preg_match("/^(wi|awi|an)/", $lanif)) {
800
			if (!is_array($config['interfaces']['lan']['wireless']))
801
				$config['interfaces']['lan']['wireless'] = array();
802
		} else {
803
			unset($config['interfaces']['lan']['wireless']);
804
		}
805

    
806
		$config['interfaces']['wan']['if'] = $wanif;
807
		if (preg_match("/^(wi|awi|an)/", $wanif)) {
808
			if (!is_array($config['interfaces']['wan']['wireless']))
809
				$config['interfaces']['wan']['wireless'] = array();
810
		} else {
811
			unset($config['interfaces']['wan']['wireless']);
812
		}
813

    
814
		for ($i = 0; $i < count($optif); $i++) {
815
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
816
				$config['interfaces']['opt' . ($i+1)] = array();
817

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

    
820
			/* wireless interface? */
821
			if (preg_match("/^(wi|awi|an)/", $optif[$i])) {
822
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
823
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
824
			} else {
825
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
826
			}
827

    
828
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
829
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
830
		}
831

    
832
		/* remove all other (old) optional interfaces */
833
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
834
			unset($config['interfaces']['opt' . ($i+1)]);
835

    
836
		write_config("NIC reconfigure");
837

    
838
		if(!$noreboot) echo "\npfSense is now rebooting.\n";
839

    
840
		echo <<<EOD
841

    
842

    
843

    
844
EOD;
845

    
846
		if($noreboot <> true)
847
			system_reboot_sync();
848
	}
849
}
850

    
851
function autodetect_interface($ifname, $fp) {
852
	$iflist_prev = get_interface_list();
853
	echo <<<EOD
854

    
855
Connect the {$ifname} interface now and make sure that the link is up.
856
Then press ENTER to continue.
857

    
858
EOD;
859
	fgets($fp);
860
	$iflist = get_interface_list();
861

    
862
	foreach ($iflist_prev as $ifn => $ifa) {
863
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
864
			echo "Detected link-up on interface {$ifn}.\n";
865
			return $ifn;
866
		}
867
	}
868

    
869
	echo "No link-up detected.\n";
870

    
871
	return null;
872
}
873

    
874
function vlan_setup() {
875
	global $iflist, $config, $g, $fp;
876

    
877
	$iflist = get_interface_list();
878

    
879
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
880

    
881
	echo <<<EOD
882

    
883
WARNING: all existing VLANs will be cleared if you proceed!
884

    
885
Do you want to proceed [y|n]?
886
EOD;
887

    
888
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
889
		return;
890
	}
891

    
892
	$config['vlans']['vlan'] = array();
893
	echo "\n";
894

    
895
	while (1) {
896
		$vlan = array();
897

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

    
901
		if ($vlan['if']) {
902
			if (!array_key_exists($vlan['if'], $iflist)) {
903
				echo "\nInvalid interface name '{$vlan['if']}'\n";
904
				continue;
905
			}
906
		} else {
907
			break;
908
		}
909

    
910
		echo "Enter the VLAN tag (1-4094): ";
911
		$vlan['tag'] = chop(fgets($fp));
912

    
913
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
914
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
915
			continue;
916
		}
917

    
918
		$config['vlans']['vlan'][] = $vlan;
919
	}
920
}
921

    
922
function system_start_ftp_helpers() {
923
	global $config;
924
	global $g;
925
	if($config['system']['disableftpproxy'] <> "") return;
926
	if ($g['booting'])
927
		echo "Starting INETD and FTP Helpers for FTP-PROXY...";
928
	$wanif = get_real_wan_interface();
929
	mwexec("/usr/sbin/inetd -wW -C 60");
930
	mwexec("/usr/bin/killall ftpsesame 2>/dev/null");
931
	mwexec("/usr/local/sbin/ftpsesame -i {$wanif} -q ftpproxy");
932
	echo "Done.\n";
933
}
934

    
935

    
936
?>
(3-3/17)