Project

General

Profile

Download (16.5 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php 
2
/*
3
	system_routes_edit.php
4
	part of m0n0wall (http://m0n0.ch/wall)
5
	
6
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
7 38936dc7 Ermal Lu?i
	Copyright (C) 2010 Scott Ullrich
8 5b237745 Scott Ullrich
	All rights reserved.
9
	
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12
	
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15
	
16
	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
	
20
	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
*/
31 1d333258 Scott Ullrich
/*
32
	pfSense_MODULE:	routing
33
*/
34 5b237745 Scott Ullrich
35 6b07c15a Matthew Grooms
##|+PRIV
36
##|*IDENT=page-system-staticroutes-editroute
37
##|*NAME=System: Static Routes: Edit route page
38
##|*DESCR=Allow access to the 'System: Static Routes: Edit route' page.
39
##|*MATCH=system_routes_edit.php*
40
##|-PRIV
41
42 4504a769 Ermal Lu?i
function staticroutecmp($a, $b) {
43
	return strcmp($a['network'], $b['network']);
44
}
45
46 0d64af59 Ermal Lu?i
function staticroutes_sort() {
47
        global $g, $config;
48
49
        if (!is_array($config['staticroutes']['route']))
50
                return;
51
52
        usort($config['staticroutes']['route'], "staticroutecmp");
53
}
54 6b07c15a Matthew Grooms
55 5b237745 Scott Ullrich
require("guiconfig.inc");
56
57
if (!is_array($config['staticroutes']['route']))
58
	$config['staticroutes']['route'] = array();
59
60
$a_routes = &$config['staticroutes']['route'];
61 6fdea6a2 smos
$a_gateways = return_gateways_array(true, true);
62 5b237745 Scott Ullrich
63
$id = $_GET['id'];
64
if (isset($_POST['id']))
65
	$id = $_POST['id'];
66
67 18f7352b Seth Mos
if (isset($_GET['dup'])) {
68
	$id = $_GET['dup'];
69
}
70
71 5b237745 Scott Ullrich
if (isset($id) && $a_routes[$id]) {
72
	list($pconfig['network'],$pconfig['network_subnet']) = 
73
		explode('/', $a_routes[$id]['network']);
74
	$pconfig['gateway'] = $a_routes[$id]['gateway'];
75
	$pconfig['descr'] = $a_routes[$id]['descr'];
76 bfe407e5 Warren Baker
	$pconfig['disabled'] = isset($a_routes[$id]['disabled']);
77 5b237745 Scott Ullrich
}
78
79 18f7352b Seth Mos
if (isset($_GET['dup']))
80
	unset($id);
81
82 5b237745 Scott Ullrich
if ($_POST) {
83
84
	unset($input_errors);
85
	$pconfig = $_POST;
86
87
	/* input validation */
88 dde169d9 Vinicius Coque
	$reqdfields = explode(" ", "network network_subnet gateway");
89 38fb1109 Vinicius Coque
	$reqdfieldsn = explode(",",
90
			gettext("Destination network") . "," .
91
			gettext("Destination network bit count") . "," .
92
			gettext("Gateway"));		
93 5b237745 Scott Ullrich
	
94
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
95
	
96 f898c1a9 jim-p
	if (($_POST['network'] && !is_ipaddr($_POST['network']) && !is_alias($_POST['network']))) {
97 ad700f39 Seth Mos
		$input_errors[] = gettext("A valid IPv4 or IPv6 destination network must be specified.");
98 5b237745 Scott Ullrich
	}
99
	if (($_POST['network_subnet'] && !is_numeric($_POST['network_subnet']))) {
100 169e0008 Carlos Eduardo Ramos
		$input_errors[] = gettext("A valid destination network bit count must be specified.");
101 5b237745 Scott Ullrich
	}
102 ad700f39 Seth Mos
	if (($_POST['gateway']) && is_ipaddr($_POST['network'])) {
103 a529aced Ermal
		if (!isset($a_gateways[$_POST['gateway']]))
104 169e0008 Carlos Eduardo Ramos
			$input_errors[] = gettext("A valid gateway must be specified.");
105 1831a00d Seth Mos
		if(!validate_address_family($_POST['network'], lookup_gateway_ip_by_name($_POST['gateway'])))
106
			$input_errors[] = gettext("The gateway '{$a_gateways[$_POST['gateway']]['gateway']}' is a different Address Family as network '{$_POST['network']}'.");
107 5b237745 Scott Ullrich
	}
108
109
	/* check for overlaps */
110 f898c1a9 jim-p
	$current_targets = get_staticroutes(true);
111
	$new_targets = array();
112 14f565b4 Seth Mos
	if(is_ipaddrv6($_POST['network'])) {
113 88cc00db Ermal
		$osn = gen_subnetv6($_POST['network'], $_POST['network_subnet']) . "/" . $_POST['network_subnet'];
114 f898c1a9 jim-p
		$new_targets[] = $osn;
115 14f565b4 Seth Mos
	}
116 71f4a2b7 smos
	if (is_ipaddrv4($_POST['network'])) {
117 1831a00d Seth Mos
		if($_POST['network_subnet'] > 32)
118
			$input_errors[] = gettext("A IPv4 subnet can not be over 32 bits.");
119 f898c1a9 jim-p
		else {
120 1831a00d Seth Mos
			$osn = gen_subnet($_POST['network'], $_POST['network_subnet']) . "/" . $_POST['network_subnet'];
121 f898c1a9 jim-p
			$new_targets[] = $osn;
122
		}
123
	} elseif (is_alias($_POST['network'])) {
124
		$osn = $_POST['network'];
125
		foreach (filter_expand_alias_array($_POST['network']) as $tgt) {
126
			if (is_ipaddr($tgt))
127
				$tgt .= "/32";
128 71f4a2b7 smos
			if (is_ipaddr($tgt))
129
				$tgt .= "/128";
130 f898c1a9 jim-p
			if (!is_subnet($tgt))
131
				continue;
132 06392e40 jim-p
			if (!is_subnetv6($tgt))
133 71f4a2b7 smos
				continue;
134 f898c1a9 jim-p
			$new_targets[] = $tgt;
135
		}
136 14f565b4 Seth Mos
	}
137 f898c1a9 jim-p
	if (!isset($id))
138
		$id = count($a_routes);
139
	$oroute = $a_routes[$id];
140 71f4a2b7 smos
	$old_targets = array();
141 f898c1a9 jim-p
	if (!empty($oroute)) {
142
		if (is_alias($oroute['network'])) {
143
			foreach (filter_expand_alias_array($oroute['network']) as $tgt) {
144
				if (is_ipaddr($tgt))
145
					$tgt .= "/32";
146
				if (!is_subnet($tgt))
147
					continue;
148
				$old_targets[] = $tgt;
149
			}
150
		} else {
151
			$old_targets[] = $oroute['network'];
152 5b237745 Scott Ullrich
		}
153
	}
154
155 f898c1a9 jim-p
	$overlaps = array_intersect($current_targets, $new_targets);
156
	$overlaps = array_diff($overlaps, $old_targets);
157
	if (count($overlaps)) {
158
		$input_errors[] = gettext("A route to these destination networks already exists") . ": " . implode(", ", $overlaps);
159
	}
160
161 74889b22 Renato Botelho
	if (is_array($config['interfaces'])) {
162
		foreach ($config['interfaces'] as $if) {
163
			if (is_ipaddrv4($_POST['network'])
164
				&& isset($if['ipaddr']) && isset($if['subnet'])
165
				&& is_ipaddrv4($if['ipaddr']) && is_numeric($if['subnet'])
166
				&& ($_POST['network_subnet'] == $if['subnet'])
167
				&& (gen_subnet($_POST['network'], $_POST['network_subnet']) == gen_subnet($if['ipaddr'], $if['subnet'])))
168
					$input_errors[] = sprintf(gettext("This network conflicts with address configured on interface %s."), $if['descr']);
169
170
			else if (is_ipaddrv6($_POST['network'])
171
				&& isset($if['ipaddrv6']) && isset($if['subnetv6'])
172
				&& is_ipaddrv6($if['ipaddrv6']) && is_numeric($if['subnetv6'])
173
				&& ($_POST['network_subnet'] == $if['subnetv6'])
174
				&& (gen_subnetv6($_POST['network'], $_POST['network_subnet']) == gen_subnetv6($if['ipaddrv6'], $if['subnetv6'])))
175
					$input_errors[] = sprintf(gettext("This network conflicts with address configured on interface %s."), $if['descr']);
176
		}
177
	}
178
179 5b237745 Scott Ullrich
	if (!$input_errors) {
180
		$route = array();
181
		$route['network'] = $osn;
182
		$route['gateway'] = $_POST['gateway'];
183
		$route['descr'] = $_POST['descr'];
184 bfe407e5 Warren Baker
		if ($_POST['disabled'])
185
			$route['disabled'] = true;
186
		else
187
			unset($route['disabled']);
188 5b237745 Scott Ullrich
189 f898c1a9 jim-p
		if (file_exists("{$g['tmp_path']}/.system_routes.apply"))
190
			$toapplylist = unserialize(file_get_contents("{$g['tmp_path']}/.system_routes.apply"));
191
		else
192
			$toapplylist = array();
193 e8471084 Ermal
		$a_routes[$id] = $route;
194
195
		if (!empty($oroute)) {
196 f898c1a9 jim-p
			$delete_targets = array_diff($old_targets, $new_targets);
197
			if (count($delete_targets))
198
				foreach ($delete_targets as $dts) {
199
					if(is_ipaddrv6($dts))
200
						$family = "-inet6";
201
					$toapplylist[] = "/sbin/route delete {$family} {$dts}"; 
202
				}
203 e8471084 Ermal
		}
204
		file_put_contents("{$g['tmp_path']}/.system_routes.apply", serialize($toapplylist));
205 0e3aa71c Erik Fonnesbeck
		staticroutes_sort();
206 5b237745 Scott Ullrich
		
207 a368a026 Ermal Lu?i
		mark_subsystem_dirty('staticroutes');
208 5b237745 Scott Ullrich
		
209
		write_config();
210
		
211
		header("Location: system_routes.php");
212
		exit;
213
	}
214
}
215 4df96eff Scott Ullrich
216 169e0008 Carlos Eduardo Ramos
$pgtitle = array(gettext("System"),gettext("Static Routes"),gettext("Edit route"));
217 b32dd0a6 jim-p
$shortcut_section = "routing";
218 4df96eff Scott Ullrich
include("head.inc");
219 5b237745 Scott Ullrich
?>
220 4df96eff Scott Ullrich
221 5b237745 Scott Ullrich
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
222 87744d53 Darren Embry
<script type="text/javascript" src="/javascript/jquery.ipv4v6ify.js"></script>
223 f898c1a9 jim-p
<script type="text/javascript" src="/javascript/autosuggest.js">
224
</script>
225
<script type="text/javascript" src="/javascript/suggestions.js">
226
</script>
227
<?php include("fbegin.inc");?>
228 5b237745 Scott Ullrich
<?php if ($input_errors) print_input_errors($input_errors); ?>
229
            <form action="system_routes_edit.php" method="post" name="iform" id="iform">
230
              <table width="100%" border="0" cellpadding="6" cellspacing="0">
231 0cece4a2 Scott Ullrich
				<tr>
232 169e0008 Carlos Eduardo Ramos
					<td colspan="2" valign="top" class="listtopic"><?=gettext("Edit route entry"); ?></td>
233 0cece4a2 Scott Ullrich
				</tr>	
234 5b237745 Scott Ullrich
                <tr>
235 169e0008 Carlos Eduardo Ramos
                  <td width="22%" valign="top" class="vncellreq"><?=gettext("Destination network"); ?></td>
236 5b237745 Scott Ullrich
                  <td width="78%" class="vtable"> 
237 f898c1a9 jim-p
                    <input name="network" type="text" class="formfldalias ipv4v6" id="network" size="20" value="<?=htmlspecialchars($pconfig['network']);?>"> 
238 5b237745 Scott Ullrich
				  / 
239 87744d53 Darren Embry
                    <select name="network_subnet" class="formselect ipv4v6" id="network_subnet"
240 bb5a2d0e Seth Mos
                      <?php
241 3d36f9d1 smos
			for ($i = 129; $i >= 1; $i--): ?>
242 5b237745 Scott Ullrich
                      <option value="<?=$i;?>" <?php if ($i == $pconfig['network_subnet']) echo "selected"; ?>>
243
                      <?=$i;?>
244
                      </option>
245
                      <?php endfor; ?>
246
                    </select>
247 169e0008 Carlos Eduardo Ramos
                    <br> <span class="vexpl"><?=gettext("Destination network for this static route"); ?></span></td>
248 5b237745 Scott Ullrich
                </tr>
249 300e2c0b Vinicius Coque
                <tr>
250 169e0008 Carlos Eduardo Ramos
                  <td width="22%" valign="top" class="vncellreq"><?=gettext("Gateway"); ?></td>
251 d173230c Seth Mos
                  <td width="78%" class="vtable">
252 38936dc7 Ermal Lu?i
			<select name="gateway" id="gateway" class="formselect">
253 d173230c Seth Mos
			<?php
254 a529aced Ermal
				foreach ($a_gateways as $gateway) {
255 a63d867a Ermal
	                      		echo "<option value='{$gateway['name']}' ";
256
					if ($gateway['name'] == $pconfig['gateway'])
257
						echo "selected";
258 189ceb32 Chris Buechler
	                      		echo ">" . htmlspecialchars($gateway['name']) . " - " . htmlspecialchars($gateway['gateway']) . "</option>\n";
259 a529aced Ermal
				}
260
			?>
261 38936dc7 Ermal Lu?i
                    </select> <br />
262
			<div id='addgwbox'>
263 ea53e38f Renato Botelho
				<?=gettext("Choose which gateway this route applies to or"); ?> <a OnClick="show_add_gateway();" href="#"><?=gettext("add a new one.");?></a>
264 38936dc7 Ermal Lu?i
								</div>
265
								<div id='notebox'>
266
								</div>
267
								<div style="display:none" name ="status" id="status">
268
								</div>								
269
								<div style="display:none" id="addgateway" name="addgateway">
270
									<p> 
271
									<table border="1" style="background:#990000; border-style: none none none none; width:225px;"><tr><td>
272
										<table bgcolor="#990000" cellpadding="1" cellspacing="1">
273
											<tr><td>&nbsp;</td>
274
											<tr>
275 ea53e38f Renato Botelho
												<td colspan="2"><center><b><font color="white"><?=gettext("Add new gateway:"); ?></b></center></td>
276 38936dc7 Ermal Lu?i
											</tr>
277
											<tr><td>&nbsp;</td>
278
											<tr>
279 a980df9c Ermal
												<td width="45%" align="right"><font color="white"><?=gettext("Default gateway:"); ?></td><td><input type="checkbox" id="defaultgw" name="defaultgw"></td>
280 38936dc7 Ermal Lu?i
											</tr>												
281
											<tr>
282 ea53e38f Renato Botelho
												<td width="45%" align="right"><font color="white"><?=gettext("Interface:"); ?></td>
283 38936dc7 Ermal Lu?i
												<td><select name="addinterfacegw" id="addinterfacegw">
284
												<?php $gwifs = get_configured_interface_with_descr();
285
													foreach($gwifs as $fif => $dif)
286
														echo "<option value=\"{$fif}\">{$dif}</option>\n";
287
												?>
288
												</select></td>
289
											</tr>
290
											<tr>
291 ea53e38f Renato Botelho
												<td align="right"><font color="white"><?=gettext("Gateway Name:"); ?></td><td><input id="name" name="name" value="GW"></td>
292 38936dc7 Ermal Lu?i
											</tr>
293
											<tr>
294 ea53e38f Renato Botelho
												<td align="right"><font color="white"><?=gettext("Gateway IP:"); ?></td><td><input id="gatewayip" name="gatewayip"></td>
295 38936dc7 Ermal Lu?i
											</tr>
296
											<tr>
297 ea53e38f Renato Botelho
												<td align="right"><font color="white"><?=gettext("Description:"); ?></td><td><input id="gatewaydescr" name="gatewaydescr"></td>
298 38936dc7 Ermal Lu?i
											</tr>
299
											<tr><td>&nbsp;</td>
300
											<tr>
301
												<td colspan="2">
302
													<center>
303
														<div id='savebuttondiv'>
304
															<input type="hidden" name="addrtype" id="addrtype" value="IPv4" />
305 169e0008 Carlos Eduardo Ramos
															<input id="gwsave" type="Button" value="<?=gettext("Save Gateway"); ?>" onClick='hide_add_gatewaysave();'> 
306
															<input id="gwcancel" type="Button" value="<?=gettext("Cancel"); ?>" onClick='hide_add_gateway();'>
307 38936dc7 Ermal Lu?i
														</div>
308
													</center>
309
												</td>
310
											</tr>
311
											<tr><td>&nbsp;</td>
312
										</table>
313
										</td></tr></table>
314
									<p/>
315
								</div>
316 5b237745 Scott Ullrich
                </tr>
317 bfe407e5 Warren Baker
		<tr>
318
			<td width="22%" valign="top" class="vncell"><?=gettext("Disabled");?></td>
319
			<td width="78%" class="vtable">
320
				<input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
321
				<strong><?=gettext("Disable this static route");?></strong><br />
322
				<span class="vexpl"><?=gettext("Set this option to disable this static route without removing it from the list.");?></span>
323
			</td>
324
		</tr>
325 d173230c Seth Mos
		<tr>
326 169e0008 Carlos Eduardo Ramos
                  <td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
327 5b237745 Scott Ullrich
                  <td width="78%" class="vtable"> 
328 b5c78501 Seth Mos
                    <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
329 ea53e38f Renato Botelho
                    <br> <span class="vexpl"><?=gettext("You may enter a description here for your reference (not parsed)."); ?></span></td>
330 5b237745 Scott Ullrich
                </tr>
331
                <tr>
332
                  <td width="22%" valign="top">&nbsp;</td>
333
                  <td width="78%"> 
334 bfb0b9dc Vinicius Coque
                    <input id="save" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancel" type="button" value="<?=gettext("Cancel"); ?>" class="formbtn"  onclick="history.back()">
335 5b237745 Scott Ullrich
                    <?php if (isset($id) && $a_routes[$id]): ?>
336 225a2f0b Scott Ullrich
                    <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>">
337 5b237745 Scott Ullrich
                    <?php endif; ?>
338
                  </td>
339
                </tr>
340
              </table>
341
</form>
342 38936dc7 Ermal Lu?i
<script type="text/javascript">
343
					var gatewayip;
344
					var name;
345
					function show_add_gateway() {
346
						document.getElementById("addgateway").style.display = '';
347
						document.getElementById("addgwbox").style.display = 'none';
348
						document.getElementById("gateway").style.display = 'none';
349
						document.getElementById("save").style.display = 'none';
350
						document.getElementById("cancel").style.display = 'none';
351
						document.getElementById("gwsave").style.display = '';
352
						document.getElementById("gwcancel").style.display = '';
353 300e2c0b Vinicius Coque
						jQuery('#notebox').html("");
354 38936dc7 Ermal Lu?i
					}
355
					function hide_add_gateway() {
356
						document.getElementById("addgateway").style.display = 'none';
357
						document.getElementById("addgwbox").style.display = '';	
358
						document.getElementById("gateway").style.display = '';
359
						document.getElementById("save").style.display = '';
360
						document.getElementById("cancel").style.display = '';
361
						document.getElementById("gwsave").style.display = '';
362
						document.getElementById("gwcancel").style.display = '';
363
					}
364
					function hide_add_gatewaysave() {
365
						document.getElementById("addgateway").style.display = 'none';
366 300e2c0b Vinicius Coque
						jQuery('#status').html('<img src="/themes/metallic/images/misc/loader.gif"> One moment please...');
367
						var iface = jQuery('#addinterfacegw').val();
368
						name = jQuery('#name').val();
369
						var descr = jQuery('#gatewaydescr').val();
370
						gatewayip = jQuery('#gatewayip').val();
371
						addrtype = jQuery('#addrtype').val();
372 a980df9c Ermal
						var defaultgw = '';
373 300e2c0b Vinicius Coque
						if (jQuery('#defaultgw').checked)
374 a980df9c Ermal
							defaultgw = 'yes';
375 38936dc7 Ermal Lu?i
						var url = "system_gateways_edit.php";
376
						var pars = 'isAjax=true&defaultgw=' + escape(defaultgw) + '&interface=' + escape(iface) + '&name=' + escape(name) + '&descr=' + escape(descr) + '&gateway=' + escape(gatewayip) + '&type=' + escape(addrtype);
377 300e2c0b Vinicius Coque
						jQuery.ajax(
378 38936dc7 Ermal Lu?i
							url,
379
							{
380 300e2c0b Vinicius Coque
								type: 'post',
381
								data: pars,
382
								error: report_failure,
383
								complete: save_callback
384
							});
385 38936dc7 Ermal Lu?i
					}
386
					function addOption(selectbox,text,value)
387
					{
388
						var optn = document.createElement("OPTION");
389
						optn.text = text;
390
						optn.value = value;
391 300e2c0b Vinicius Coque
						selectbox.append(optn);
392
						selectbox.prop('selectedIndex',selectbox.children('option').length-1);
393
						jQuery('#notebox').html("<p/><strong><?=gettext("NOTE:");?></strong> <?php printf(gettext("You can manage Gateways %shere%s."), "<a target='_new' href='system_gateways.php'>", "</a>");?> </strong>");
394 38936dc7 Ermal Lu?i
					}				
395
					function report_failure() {
396 ea53e38f Renato Botelho
						alert("<?=gettext("Sorry, we could not create your gateway at this time."); ?>");
397 38936dc7 Ermal Lu?i
						hide_add_gateway();
398
					}
399
					function save_callback(transport) {
400
						var response = transport.responseText;
401
						if (response) {
402
							document.getElementById("addgateway").style.display = 'none';
403
							hide_add_gateway();
404 300e2c0b Vinicius Coque
							jQuery('#status').html('');
405
							addOption(jQuery('#gateway'), name, name);
406 38936dc7 Ermal Lu?i
						} else {
407
							report_failure();
408
						}
409
					}
410 4dfd930e Darren Embry
					var addressarray = <?= json_encode(get_alias_list(array("host", "network"))) ?>;
411 f898c1a9 jim-p
					var oTextbox1 = new AutoSuggestControl(document.getElementById("network"), new StateSuggestions(addressarray));
412
413 38936dc7 Ermal Lu?i
				</script>
414 5b237745 Scott Ullrich
<?php include("fend.inc"); ?>
415
</body>
416
</html>