Project

General

Profile

Download (12.8 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 b46bfcf5 Bill Marquette
/* $Id$ */
3 5b237745 Scott Ullrich
/*
4 197bfe96 Ermal Luçi
	firewall_shaper.php
5
	Copyright (C) 2004, 2005 Scott Ullrich
6 1d7ba683 ayvis
	Copyright (C) 2008 Ermal Luçi
7 ce77a9c4 Phil Davis
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
8 197bfe96 Ermal Luçi
	All rights reserved.
9 b49448ac Scott Ullrich
10 197bfe96 Ermal Luçi
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12 b49448ac Scott Ullrich
13 197bfe96 Ermal Luçi
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15 b49448ac Scott Ullrich
16 197bfe96 Ermal Luçi
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19 b49448ac Scott Ullrich
20 197bfe96 Ermal Luçi
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30 5b237745 Scott Ullrich
*/
31 7ac5a4cb Scott Ullrich
/*
32
	pfSense_BUILDER_BINARIES:	/usr/bin/killall
33
	pfSense_MODULE:	shaper
34
*/
35 5b237745 Scott Ullrich
36 6b07c15a Matthew Grooms
##|+PRIV
37
##|*IDENT=page-firewall-trafficshaper
38
##|*NAME=Firewall: Traffic Shaper page
39
##|*DESCR=Allow access to the 'Firewall: Traffic Shaper' page.
40
##|*MATCH=firewall_shaper.php*
41
##|-PRIV
42
43 5b237745 Scott Ullrich
require("guiconfig.inc");
44 7a927e67 Scott Ullrich
require_once("functions.inc");
45
require_once("filter.inc");
46
require_once("shaper.inc");
47 a5f07f09 Ermal Lu?i
require_once("rrd.inc");
48 5b237745 Scott Ullrich
49 6aaec445 Phil Davis
if ($_GET['reset'] <> "") {
50 7ac5a4cb Scott Ullrich
	/* XXX: Huh, why are we killing php? */
51
	mwexec("killall -9 pfctl php");
52 8f8a97c8 Ermal Luçi
	exit;
53 1b2c6c29 Ermal Luçi
}
54
55 4e52fac4 Carlos Eduardo Ramos
$pgtitle = array(gettext("Firewall"),gettext("Traffic Shaper"));
56 b32dd0a6 jim-p
$shortcut_section = "trafficshaper";
57 09eafb8b Scott Ullrich
58 9d5b21c6 Ermal Luçi
$shaperIFlist = get_configured_interface_with_descr();
59 197bfe96 Ermal Luçi
read_altq_config();
60 6aaec445 Phil Davis
/*
61 197bfe96 Ermal Luçi
 * The whole logic in these code maybe can be specified.
62
 * If you find a better way contact me :).
63
 */
64 57b89461 Scott Ullrich
65 197bfe96 Ermal Luçi
if ($_GET) {
66 6aaec445 Phil Davis
	if ($_GET['queue']) {
67 e52c3c88 jim-p
		$qname = htmlspecialchars(trim($_GET['queue']));
68 6aaec445 Phil Davis
	}
69
	if ($_GET['interface']) {
70
		$interface = htmlspecialchars(trim($_GET['interface']));
71
	}
72
	if ($_GET['action']) {
73
		$action = htmlspecialchars($_GET['action']);
74
	}
75 197bfe96 Ermal Luçi
}
76
if ($_POST) {
77 6aaec445 Phil Davis
	if ($_POST['name']) {
78
		$qname = htmlspecialchars(trim($_POST['name']));
79
	}
80
	if ($_POST['interface']) {
81
		$interface = htmlspecialchars(trim($_POST['interface']));
82
	}
83
	if ($_POST['parentqueue']) {
84 daab67a1 Scott Ullrich
		$parentqueue = htmlspecialchars(trim($_POST['parentqueue']));
85 6aaec445 Phil Davis
	}
86 57b89461 Scott Ullrich
}
87
88 197bfe96 Ermal Luçi
if ($interface) {
89
	$altq = $altq_list_queues[$interface];
90
	if ($altq) {
91
		$queue =& $altq->find_queue($interface, $qname);
92 6aaec445 Phil Davis
	} else {
93
		$addnewaltq = true;
94
	}
95 57b89461 Scott Ullrich
}
96
97 197bfe96 Ermal Luçi
$dontshow = false;
98
$newqueue = false;
99 92125c97 Ermal Luçi
$output_form = "";
100 5b237745 Scott Ullrich
101 197bfe96 Ermal Luçi
if ($_GET) {
102
	switch ($action) {
103 6aaec445 Phil Davis
		case "delete":
104 197bfe96 Ermal Luçi
			if ($queue) {
105
				$queue->delete_queue();
106 6aaec445 Phil Davis
				if (write_config()) {
107 3a343d73 jim-p
					mark_subsystem_dirty('shaper');
108 6aaec445 Phil Davis
				}
109 197bfe96 Ermal Luçi
			}
110
			header("Location: firewall_shaper.php");
111
			exit;
112 6aaec445 Phil Davis
			break;
113
		case "resetall":
114
			foreach ($altq_list_queues as $altq) {
115 26dfbf80 Ermal Luçi
				$altq->delete_all();
116 6aaec445 Phil Davis
			}
117 26dfbf80 Ermal Luçi
			unset($altq_list_queues);
118
			$altq_list_queues = array();
119
			$tree = "<ul class=\"tree\" >";
120
			$tree .= get_interface_list_to_show();
121
			$tree .= "</ul>";
122
			unset($config['shaper']['queue']);
123
			unset($queue);
124
			unset($altq);
125
			$can_add = false;
126
			$can_enable = false;
127
			$dontshow = true;
128
			foreach ($config['filter']['rule'] as $key => $rule) {
129 6aaec445 Phil Davis
				if (isset($rule['wizard']) && $rule['wizard'] == "yes") {
130 26dfbf80 Ermal Luçi
					unset($config['filter']['rule'][$key]);
131 6aaec445 Phil Davis
				}
132 26dfbf80 Ermal Luçi
			}
133 3a343d73 jim-p
			if (write_config()) {
134
				$retval = 0;
135
				$retval |= filter_configure();
136
				$savemsg = get_std_save_message($retval);
137 26dfbf80 Ermal Luçi
138 6aaec445 Phil Davis
				if (stristr($retval, "error") <> true) {
139 3a343d73 jim-p
					$savemsg = get_std_save_message($retval);
140 6aaec445 Phil Davis
				} else {
141 3a343d73 jim-p
					$savemsg = $retval;
142 6aaec445 Phil Davis
				}
143 3a343d73 jim-p
			} else {
144
				$savemsg = gettext("Unable to write config.xml (Access Denied?)");
145
			}
146 26dfbf80 Ermal Luçi
			$output_form = $default_shaper_message;
147
148 6aaec445 Phil Davis
			break;
149
		case "add":
150 197bfe96 Ermal Luçi
			/* XXX: Find better way because we shouldn't know about this */
151 6aaec445 Phil Davis
			if ($altq) {
152
				switch ($altq->GetScheduler()) {
153
					case "PRIQ":
154
						$q = new priq_queue();
155
						break;
156
					case "FAIRQ":
157
						$q = new fairq_queue();
158
						break;
159
					case "HFSC":
160
						$q = new hfsc_queue();
161
						break;
162
					case "CBQ":
163
						$q = new cbq_queue();
164
						break;
165
					default:
166
						/* XXX: Happens when sched==NONE?! */
167
						$q = new altq_root_queue();
168
						break;
169
				}
170
			} else if ($addnewaltq) {
171 197bfe96 Ermal Luçi
				$q = new altq_root_queue();
172 6aaec445 Phil Davis
			} else {
173 1c52312d Jeann
			$input_errors[] = gettext("Could not create new queue/discipline!");
174 6aaec445 Phil Davis
			}
175 197bfe96 Ermal Luçi
176
			if ($q) {
177
				$q->SetInterface($interface);
178 92125c97 Ermal Luçi
				$output_form .= $q->build_form();
179
				$output_form .= "<input type=\"hidden\" name=\"parentqueue\" id=\"parentqueue\"";
180 e52c3c88 jim-p
				$output_form .= " value=\"".htmlspecialchars($qname)."\" />";
181 bdb0d479 Ermal Luçi
				$newjavascript = $q->build_javascript();
182 6aaec445 Phil Davis
				unset($q);
183 197bfe96 Ermal Luçi
				$newqueue = true;
184
			}
185 6aaec445 Phil Davis
			break;
186 197bfe96 Ermal Luçi
		case "show":
187 6aaec445 Phil Davis
			if ($queue) {
188
				$output_form .= $queue->build_form();
189
			} else {
190
				$input_errors[] = gettext("Queue not found!");
191
			}
192
			break;
193 197bfe96 Ermal Luçi
		case "enable":
194
			if ($queue) {
195
					$queue->SetEnabled("on");
196 92125c97 Ermal Luçi
					$output_form .= $queue->build_form();
197 3a343d73 jim-p
					if (write_config())
198
						mark_subsystem_dirty('shaper');
199 6aaec445 Phil Davis
			} else {
200 1c52312d Jeann
					$input_errors[] = gettext("Queue not found!");
201 6aaec445 Phil Davis
			}
202
			break;
203 197bfe96 Ermal Luçi
		case "disable":
204
			if ($queue) {
205 6aaec445 Phil Davis
				$queue->SetEnabled("");
206
				$output_form .= $queue->build_form();
207
				if (write_config()) {
208
					mark_subsystem_dirty('shaper');
209
				}
210
			} else {
211 1c52312d Jeann
					$input_errors[] = gettext("Queue not found!");
212 6aaec445 Phil Davis
			}
213
			break;
214 197bfe96 Ermal Luçi
		default:
215 4eb7d4d7 Colin Fleming
			$output_form .= $default_shaper_msg;
216 197bfe96 Ermal Luçi
			$dontshow = true;
217
			break;
218 5b237745 Scott Ullrich
	}
219 197bfe96 Ermal Luçi
} else if ($_POST) {
220
	unset($input_errors);
221 5b237745 Scott Ullrich
222 197bfe96 Ermal Luçi
	if ($addnewaltq) {
223 23ca5695 Chris Buechler
		$altq =& new altq_root_queue();
224 197bfe96 Ermal Luçi
		$altq->SetInterface($interface);
225 6aaec445 Phil Davis
226 92125c97 Ermal Luçi
		switch ($altq->GetBwscale()) {
227 6aaec445 Phil Davis
			case "Mb":
228
				$factor = 1000 * 1000;
229
				brak;
230
			case "Kb":
231
				$factor = 1000;
232
				break;
233
			case "b":
234
				$factor = 1;
235
				break;
236
			case "Gb":
237
				$factor = 1000 * 1000 * 1000;
238
				break;
239
			case "%": /* We don't use it for root_XXX queues. */
240
			default: /* XXX assume Kb by default. */
241
				$factor = 1000;
242
				break;
243
		}
244 92125c97 Ermal Luçi
		$altq->SetAvailableBandwidth($altq->GetBandwidth() * $factor);
245 197bfe96 Ermal Luçi
		$altq->ReadConfig($_POST);
246 ea51e9f8 Renato Botelho
		$altq->validate_input($_POST, $input_errors);
247 92125c97 Ermal Luçi
		if (!$input_errors) {
248
			unset($tmppath);
249
			$tmppath[] = $altq->GetInterface();
250 6aaec445 Phil Davis
			$altq->SetLink($tmppath);
251 92125c97 Ermal Luçi
			$altq->wconfig();
252 6aaec445 Phil Davis
			if (write_config()) {
253 3a343d73 jim-p
				mark_subsystem_dirty('shaper');
254 6aaec445 Phil Davis
			}
255 92125c97 Ermal Luçi
			$can_enable = true;
256 6aaec445 Phil Davis
			$can_add = true;
257 92125c97 Ermal Luçi
		}
258 48d418e8 Ermal Luçi
		read_altq_config();
259 92125c97 Ermal Luçi
		$output_form .= $altq->build_form();
260
261 197bfe96 Ermal Luçi
	} else if ($parentqueue) { /* Add a new queue */
262
		$qtmp =& $altq->find_queue($interface, $parentqueue);
263
		if ($qtmp) {
264
			$tmppath =& $qtmp->GetLink();
265
			array_push($tmppath, $qname);
266 ea51e9f8 Renato Botelho
			$tmp =& $qtmp->add_queue($interface, $_POST, $tmppath, $input_errors);
267 92125c97 Ermal Luçi
			if (!$input_errors) {
268
				array_pop($tmppath);
269
				$tmp->wconfig();
270
				$can_enable = true;
271 70b139a3 Chris Buechler
				if ($tmp->CanHaveChildren() && $can_enable) {
272 6aaec445 Phil Davis
					if ($tmp->GetDefault() <> "") {
273
						$can_add = false;
274
					} else {
275
						$can_add = true;
276
					}
277
				} else {
278 92125c97 Ermal Luçi
					$can_add = false;
279 6aaec445 Phil Davis
				}
280
				if (write_config()) {
281 3a343d73 jim-p
					mark_subsystem_dirty('shaper');
282 6aaec445 Phil Davis
				}
283 92125c97 Ermal Luçi
				$can_enable = true;
284 6aaec445 Phil Davis
				if ($altq->GetScheduler() != "PRIQ") { /* XXX */
285
					if ($tmp->GetDefault() <> "") {
286
						$can_add = false;
287
					} else {
288
						$can_add = true;
289
					}
290
				}
291 92125c97 Ermal Luçi
			}
292 48d418e8 Ermal Luçi
			read_altq_config();
293 6aaec445 Phil Davis
			$output_form .= $tmp->build_form();
294
		} else {
295 2f8fe6af Carlos Eduardo Ramos
			$input_errors[] = gettext("Could not add new queue.");
296 6aaec445 Phil Davis
		}
297 197bfe96 Ermal Luçi
	} else if ($_POST['apply']) {
298 6aaec445 Phil Davis
		write_config();
299 0df08a41 Scott Ullrich
300 6aaec445 Phil Davis
		$retval = 0;
301
		$retval = filter_configure();
302
		$savemsg = get_std_save_message($retval);
303
304
		if (stristr($retval, "error") <> true) {
305 0027de0a Ermal Lu?i
			$savemsg = get_std_save_message($retval);
306 6aaec445 Phil Davis
		} else {
307
			$savemsg = $retval;
308
		}
309 5b237745 Scott Ullrich
310 6aaec445 Phil Davis
		/* reset rrd queues */
311 7ac5a4cb Scott Ullrich
		system("rm -f /var/db/rrd/*queuedrops.rrd");
312
		system("rm -f /var/db/rrd/*queues.rrd");
313
		enable_rrd_graphing();
314 1f276138 Scott Ullrich
315 a368a026 Ermal Lu?i
		clear_subsystem_dirty('shaper');
316 1f276138 Scott Ullrich
317 6aaec445 Phil Davis
		if ($queue) {
318
			$output_form .= $queue->build_form();
319
			$dontshow = false;
320
		} else {
321
			$output_form .= $default_shaper_message;
322
			$dontshow = true;
323
		}
324 197bfe96 Ermal Luçi
	} else if ($queue) {
325 6aaec445 Phil Davis
		$queue->validate_input($_POST, $input_errors);
326
		if (!$input_errors) {
327
			$queue->update_altq_queue_data($_POST);
328
			$queue->wconfig();
329
			if (write_config()) {
330
				mark_subsystem_dirty('shaper');
331
			}
332
			$dontshow = false;
333
		}
334 48d418e8 Ermal Luçi
		read_altq_config();
335
		$output_form .= $queue->build_form();
336 92125c97 Ermal Luçi
	} else  {
337 4eb7d4d7 Colin Fleming
		$output_form .= $default_shaper_msg;
338 92125c97 Ermal Luçi
		$dontshow = true;
339
	}
340 5f471c95 Ermal
	mwexec("killall qstats");
341 0ceb8927 Bill Marquette
} else {
342 4eb7d4d7 Colin Fleming
	$output_form .= $default_shaper_msg;
343 197bfe96 Ermal Luçi
	$dontshow = true;
344
}
345 0ceb8927 Bill Marquette
346 fce82460 Ermal Luçi
if ($queue) {
347 6aaec445 Phil Davis
	if ($queue->GetEnabled()) {
348
		$can_enable = true;
349
	} else {
350
		$can_enable = false;
351
	}
352
	if ($queue->CanHaveChildren() && $can_enable) {
353
		if ($altq->GetQname() <> $queue->GetQname() && $queue->GetDefault() <> "") {
354
			$can_add = false;
355
		} else {
356
			$can_add = true;
357
		}
358
	} else {
359
		$can_add = false;
360
	}
361 fce82460 Ermal Luçi
}
362
363
$tree = "<ul class=\"tree\" >";
364
if (is_array($altq_list_queues)) {
365 6aaec445 Phil Davis
	foreach ($altq_list_queues as $tmpaltq) {
366
		$tree .= $tmpaltq->build_tree();
367
	}
368
	$tree .= get_interface_list_to_show();
369 fce82460 Ermal Luçi
}
370
$tree .= "</ul>";
371 0ceb8927 Bill Marquette
372 197bfe96 Ermal Luçi
if (!$dontshow || $newqueue) {
373 0ceb8927 Bill Marquette
374 6aaec445 Phil Davis
	$output_form .= "<tr><td width=\"22%\" valign=\"middle\" class=\"vncellreq\">";
375
	$output_form .= "<br />" . gettext("Queue Actions") . "<br />";
376
	$output_form .= "</td><td valign=\"middle\" class=\"vncellreq\" width=\"78%\"><br />";
377 197bfe96 Ermal Luçi
378 6aaec445 Phil Davis
	$output_form .= "<input type=\"submit\" name=\"Submit\" value=\"" . gettext("Save") . "\" class=\"formbtn\" />";
379
	if ($can_add || $addnewaltq) {
380
		$output_form .= "<a href=\"firewall_shaper.php?interface=";
381
		$output_form .= $interface;
382
		if ($queue) {
383
			$output_form .= "&amp;queue=" . $queue->GetQname();
384
		}
385
		$output_form .= "&amp;action=add\">";
386
		$output_form .= "<input type=\"button\" class=\"formbtn\" name=\"add\" value=\"" . gettext("Add new queue") . "\" />";
387
		$output_form .= "</a>";
388
	}
389 92125c97 Ermal Luçi
	$output_form .= "<a href=\"firewall_shaper.php?interface=";
390 6aaec445 Phil Davis
	$output_form .= $interface . "&amp;queue=";
391 92125c97 Ermal Luçi
	if ($queue) {
392 df5c0bc0 Colin Fleming
		$output_form .= "&amp;queue=" . $queue->GetQname();
393 92125c97 Ermal Luçi
	}
394 6aaec445 Phil Davis
	$output_form .= "&amp;action=delete\">";
395
	$output_form .= "<input type=\"button\" class=\"formbtn\" name=\"delete\"";
396
	if ($queue) {
397
		$output_form .= " value=\"" . gettext("Delete this queue") . "\" />";
398
	} else {
399
		$output_form .= " value=\"" . gettext("Disable shaper on interface") . "\" />";
400
	}
401 92125c97 Ermal Luçi
	$output_form .= "</a>";
402 6aaec445 Phil Davis
	$output_form .= "<br /></td></tr>";
403
	$output_form .= "</table>";
404
} else {
405 4eb7d4d7 Colin Fleming
	$output_form .= "</table>";
406 6aaec445 Phil Davis
}
407 92125c97 Ermal Luçi
408 4eb7d4d7 Colin Fleming
$output = "<table  summary=\"output form\">";
409 92125c97 Ermal Luçi
$output .= $output_form;
410 52380979 Scott Ullrich
411 58dc3a03 Ermal Luçi
//$pgtitle = "Firewall: Shaper: By Interface View";
412 df5c0bc0 Colin Fleming
$closehead = false;
413 197bfe96 Ermal Luçi
include("head.inc");
414 5b237745 Scott Ullrich
?>
415 197bfe96 Ermal Luçi
<link rel="stylesheet" type="text/css" media="all" href="./tree/tree.css" />
416
<script type="text/javascript" src="./tree/tree.js"></script>
417 df5c0bc0 Colin Fleming
</head>
418
419
<body link="#0000CC" vlink="#0000CC" alink="#0000CC" >
420 92125c97 Ermal Luçi
<?php
421 6aaec445 Phil Davis
if ($queue) {
422
		echo $queue->build_javascript();
423
}
424 bdb0d479 Ermal Luçi
echo $newjavascript;
425 5b237745 Scott Ullrich
426 6aaec445 Phil Davis
include("fbegin.inc");
427 92125c97 Ermal Luçi
?>
428 197bfe96 Ermal Luçi
<div id="inputerrors"></div>
429
<?php if ($input_errors) print_input_errors($input_errors); ?>
430
431 92125c97 Ermal Luçi
<form action="firewall_shaper.php" method="post" id="iform" name="iform">
432 197bfe96 Ermal Luçi
433 5b237745 Scott Ullrich
<?php if ($savemsg) print_info_box($savemsg); ?>
434 a368a026 Ermal Lu?i
<?php if (is_subsystem_dirty('shaper')): ?><p>
435 1d7ba683 ayvis
<?php print_info_box_np(gettext("The traffic shaper configuration has been changed.")."<br />".gettext("You must apply the changes in order for them to take effect."));?><br /></p>
436 5b237745 Scott Ullrich
<?php endif; ?>
437 df5c0bc0 Colin Fleming
<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="traffic shaper">
438 6aaec445 Phil Davis
	<tr><td>
439 52380979 Scott Ullrich
<?php
440
	$tab_array = array();
441 1c52312d Jeann
	$tab_array[0] = array(gettext("By Interface"), true, "firewall_shaper.php");
442
	$tab_array[1] = array(gettext("By Queue"), false, "firewall_shaper_queues.php");
443
	$tab_array[2] = array(gettext("Limiter"), false, "firewall_shaper_vinterface.php");
444
	$tab_array[3] = array(gettext("Layer7"), false, "firewall_shaper_layer7.php");
445
	$tab_array[4] = array(gettext("Wizards"), false, "firewall_shaper_wizards.php");
446 52380979 Scott Ullrich
	display_top_tabs($tab_array);
447 197bfe96 Ermal Luçi
?>
448 6aaec445 Phil Davis
	</td></tr>
449
	<tr>
450
		<td>
451
			<div id="mainarea">
452
				<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0" summary="main area">
453 26dfbf80 Ermal Luçi
<?php if (count($altq_list_queues) > 0): ?>
454 6aaec445 Phil Davis
					<tr class="tabcont">
455
						<td width="25%" align="left">
456
							<a href="firewall_shaper.php?action=resetall" >
457
								<input type="button" value="<?=gettext("Remove Shaper")?>" class="formbtn" />
458
							</a>
459
						</td>
460
						<td width="75%"> </td>
461
					</tr>
462 ee9933b6 Renato Botelho
<?php endif; ?>
463 6aaec445 Phil Davis
					<tr>
464
						<td width="25%" valign="top" align="left">
465
						<?php
466
							echo $tree;
467
						?>
468
						</td>
469
						<td width="75%" valign="top" align="center">
470
							<div id="shaperarea" style="position:relative">
471
							<?php
472
								echo $output;
473
							?>
474
							</div>
475
						</td>
476
					</tr>
477
				</table>
478 4eb7d4d7 Colin Fleming
			</div>
479 6aaec445 Phil Davis
		</td>
480 5b237745 Scott Ullrich
	</tr>
481
</table>
482 6aaec445 Phil Davis
</form>
483 df5c0bc0 Colin Fleming
<?php include("fend.inc"); ?>
484 5b237745 Scott Ullrich
</body>
485
</html>