Project

General

Profile

Download (15.7 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
#!/usr/local/bin/php
2 9ae40f2b Scott Ullrich
<?php
3 b46bfcf5 Bill Marquette
/* $Id$ */
4 5b237745 Scott Ullrich
/*
5
	firewall_nat_edit.php
6
	part of m0n0wall (http://m0n0.ch/wall)
7 9ae40f2b Scott Ullrich
8 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10 9ae40f2b Scott Ullrich
11 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13 9ae40f2b Scott Ullrich
14 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16 9ae40f2b Scott Ullrich
17 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
18
	   notice, this list of conditions and the following disclaimer in the
19
	   documentation and/or other materials provided with the distribution.
20 9ae40f2b Scott Ullrich
21 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
	POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
require("guiconfig.inc");
34
35
if (!is_array($config['nat']['rule'])) {
36
	$config['nat']['rule'] = array();
37
}
38 e99989d8 Scott Ullrich
//nat_rules_sort();
39 5b237745 Scott Ullrich
$a_nat = &$config['nat']['rule'];
40
41
$id = $_GET['id'];
42
if (isset($_POST['id']))
43
	$id = $_POST['id'];
44
45 4a991889 Bill Marquette
if (isset($_GET['dup'])) {
46
        $id = $_GET['dup'];
47
        $after = $_GET['dup'];
48
}
49
50 5b237745 Scott Ullrich
if (isset($id) && $a_nat[$id]) {
51
	$pconfig['extaddr'] = $a_nat[$id]['external-address'];
52
	$pconfig['proto'] = $a_nat[$id]['protocol'];
53
	list($pconfig['beginport'],$pconfig['endport']) = explode("-", $a_nat[$id]['external-port']);
54
	$pconfig['localip'] = $a_nat[$id]['target'];
55
	$pconfig['localbeginport'] = $a_nat[$id]['local-port'];
56
	$pconfig['descr'] = $a_nat[$id]['descr'];
57
	$pconfig['interface'] = $a_nat[$id]['interface'];
58
	if (!$pconfig['interface'])
59
		$pconfig['interface'] = "wan";
60
} else {
61
	$pconfig['interface'] = "wan";
62
}
63
64 a6713b32 Bill Marquette
if (isset($_GET['dup']))
65
	unset($id);
66
67 5b237745 Scott Ullrich
if ($_POST) {
68
69
	if ($_POST['beginport_cust'] && !$_POST['beginport'])
70
		$_POST['beginport'] = $_POST['beginport_cust'];
71
	if ($_POST['endport_cust'] && !$_POST['endport'])
72
		$_POST['endport'] = $_POST['endport_cust'];
73
	if ($_POST['localbeginport_cust'] && !$_POST['localbeginport'])
74
		$_POST['localbeginport'] = $_POST['localbeginport_cust'];
75 9ae40f2b Scott Ullrich
76 5b237745 Scott Ullrich
	if (!$_POST['endport'])
77
		$_POST['endport'] = $_POST['beginport'];
78 9ae40f2b Scott Ullrich
79 5b237745 Scott Ullrich
	unset($input_errors);
80
	$pconfig = $_POST;
81
82
	/* input validation */
83 b66f7667 Scott Ullrich
	if($_POST['proto'] == "TCP" or $_POST['proto'] == "UDP" or $_POST['proto'] == "TCP/UDP") {
84
		$reqdfields = explode(" ", "interface proto beginport localip localbeginport");
85
		$reqdfieldsn = explode(",", "Interface,Protocol,Start port,NAT IP,Local port");
86
	} else {
87
		$reqdfields = explode(" ", "interface proto localip");
88
		$reqdfieldsn = explode(",", "Interface,Protocol,NAT IP");		
89
	}
90 9ae40f2b Scott Ullrich
91 5b237745 Scott Ullrich
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
92 9ae40f2b Scott Ullrich
93 5b237745 Scott Ullrich
	if (($_POST['localip'] && !is_ipaddroralias($_POST['localip']))) {
94 5eb817bc Bill Marquette
		$input_errors[] = "\"{$_POST['localip']}\" is not valid NAT IP address or host alias.";
95 5b237745 Scott Ullrich
	}
96 9ae40f2b Scott Ullrich
97 b66f7667 Scott Ullrich
	/* only validate the ports if the protocol is TCP, UDP or TCP/UDP */
98
	if($_POST['proto'] == "TCP" or $_POST['proto'] == "UDP" or $_POST['proto'] == "TCP/UDP") {
99 9ae40f2b Scott Ullrich
100 b66f7667 Scott Ullrich
		if (($_POST['beginport'] && !is_ipaddroralias($_POST['beginport']) && !is_port($_POST['beginport']))) {
101
			$input_errors[] = "The start port must be an integer between 1 and 65535.";
102
		}
103
104
		if (($_POST['endport'] && !is_ipaddroralias($_POST['endport']) && !is_port($_POST['endport']))) {
105
			$input_errors[] = "The end port must be an integer between 1 and 65535.";
106
		}
107
108
		if (($_POST['localbeginport'] && !is_ipaddroralias($_POST['localbeginport']) && !is_port($_POST['localbeginport']))) {
109
			$input_errors[] = "The local port must be an integer between 1 and 65535.";
110
		}
111
112
		if ($_POST['beginport'] > $_POST['endport']) {
113
			/* swap */
114
			$tmp = $_POST['endport'];
115
			$_POST['endport'] = $_POST['beginport'];
116
			$_POST['beginport'] = $tmp;
117
		}
118
119
		if (!$input_errors) {
120
			if (($_POST['endport'] - $_POST['beginport'] + $_POST['localbeginport']) > 65535)
121
				$input_errors[] = "The target port range must be an integer between 1 and 65535.";
122
		}
123
		
124 5b237745 Scott Ullrich
	}
125 9ae40f2b Scott Ullrich
126 5b237745 Scott Ullrich
	/* check for overlaps */
127
	foreach ($a_nat as $natent) {
128
		if (isset($id) && ($a_nat[$id]) && ($a_nat[$id] === $natent))
129
			continue;
130
		if ($natent['interface'] != $_POST['interface'])
131
			continue;
132
		if ($natent['external-address'] != $_POST['extaddr'])
133
			continue;
134 9ae40f2b Scott Ullrich
135 5b237745 Scott Ullrich
		list($begp,$endp) = explode("-", $natent['external-port']);
136
		if (!$endp)
137
			$endp = $begp;
138 9ae40f2b Scott Ullrich
139 5b237745 Scott Ullrich
		if (!(   (($_POST['beginport'] < $begp) && ($_POST['endport'] < $begp))
140
		      || (($_POST['beginport'] > $endp) && ($_POST['endport'] > $endp)))) {
141 9ae40f2b Scott Ullrich
142 5b237745 Scott Ullrich
			$input_errors[] = "The external port range overlaps with an existing entry.";
143
			break;
144
		}
145
	}
146
147
	if (!$input_errors) {
148
		$natent = array();
149
		if ($_POST['extaddr'])
150
			$natent['external-address'] = $_POST['extaddr'];
151
		$natent['protocol'] = $_POST['proto'];
152 9ae40f2b Scott Ullrich
153 5b237745 Scott Ullrich
		if ($_POST['beginport'] == $_POST['endport'])
154
			$natent['external-port'] = $_POST['beginport'];
155
		else
156
			$natent['external-port'] = $_POST['beginport'] . "-" . $_POST['endport'];
157 9ae40f2b Scott Ullrich
158 5b237745 Scott Ullrich
		$natent['target'] = $_POST['localip'];
159
		$natent['local-port'] = $_POST['localbeginport'];
160
		$natent['interface'] = $_POST['interface'];
161
		$natent['descr'] = $_POST['descr'];
162 9ae40f2b Scott Ullrich
163 5b237745 Scott Ullrich
		if (isset($id) && $a_nat[$id])
164
			$a_nat[$id] = $natent;
165 4a991889 Bill Marquette
		else {
166
			if (is_numeric($after))
167
				array_splice($a_nat, $after+1, 0, array($natent));
168
			else
169
				$a_nat[] = $natent;
170
		}
171 9ae40f2b Scott Ullrich
172 5b237745 Scott Ullrich
		touch($d_natconfdirty_path);
173 9ae40f2b Scott Ullrich
174 5b237745 Scott Ullrich
		if ($_POST['autoadd']) {
175
			/* auto-generate a matching firewall rule */
176 9ae40f2b Scott Ullrich
			$filterent = array();
177 5b237745 Scott Ullrich
			$filterent['interface'] = $_POST['interface'];
178
			$filterent['protocol'] = $_POST['proto'];
179
			$filterent['source']['any'] = "";
180
			$filterent['destination']['address'] = $_POST['localip'];
181 9ae40f2b Scott Ullrich
182 5b237745 Scott Ullrich
			$dstpfrom = $_POST['localbeginport'];
183
			$dstpto = $dstpfrom + $_POST['endport'] - $_POST['beginport'];
184 9ae40f2b Scott Ullrich
185 5b237745 Scott Ullrich
			if ($dstpfrom == $dstpto)
186
				$filterent['destination']['port'] = $dstpfrom;
187
			else
188
				$filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
189 9ae40f2b Scott Ullrich
190 5b237745 Scott Ullrich
			$filterent['descr'] = "NAT " . $_POST['descr'];
191 9ae40f2b Scott Ullrich
192 5b237745 Scott Ullrich
			$config['filter']['rule'][] = $filterent;
193 9ae40f2b Scott Ullrich
194 5b237745 Scott Ullrich
			touch($d_filterconfdirty_path);
195
		}
196 9ae40f2b Scott Ullrich
197 5b237745 Scott Ullrich
		write_config();
198 9ae40f2b Scott Ullrich
199 5b237745 Scott Ullrich
		header("Location: firewall_nat.php");
200
		exit;
201
	}
202
}
203 da7ae7ef Bill Marquette
204 183a4aae Bill Marquette
$pgtitle = "Firewall: NAT: Port Forward: Edit";
205 da7ae7ef Bill Marquette
include("head.inc");
206
207 5b237745 Scott Ullrich
?>
208 da7ae7ef Bill Marquette
209 5b237745 Scott Ullrich
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
210 4ce8ac00 Erik Kristensen
<?php
211
include("fbegin.inc"); ?>
212 da7ae7ef Bill Marquette
<p class="pgtitle"><?=$pgtitle?></p>
213 5b237745 Scott Ullrich
<?php if ($input_errors) print_input_errors($input_errors); ?>
214
            <form action="firewall_nat_edit.php" method="post" name="iform" id="iform">
215
              <table width="100%" border="0" cellpadding="6" cellspacing="0">
216 183a4aae Bill Marquette
	  	<tr>
217 5b237745 Scott Ullrich
                  <td width="22%" valign="top" class="vncellreq">Interface</td>
218
                  <td width="78%" class="vtable">
219
					<select name="interface" class="formfld">
220
						<?php
221 b1f66041 Scott Ullrich
						$interfaces = array('wan' => 'WAN', 'lan' => 'LAN', 'pptp' => 'PPTP');
222 5b237745 Scott Ullrich
						for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
223
							$interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
224
						}
225
						foreach ($interfaces as $iface => $ifacename): ?>
226
						<option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
227
						<?=htmlspecialchars($ifacename);?>
228
						</option>
229
						<?php endforeach; ?>
230
					</select><br>
231
                     <span class="vexpl">Choose which interface this rule applies to.<br>
232
                     Hint: in most cases, you'll want to use WAN here.</span></td>
233
                </tr>
234 9ae40f2b Scott Ullrich
			    <tr>
235 5b237745 Scott Ullrich
                  <td width="22%" valign="top" class="vncellreq">External address</td>
236 9ae40f2b Scott Ullrich
                  <td width="78%" class="vtable">
237 4ce8ac00 Erik Kristensen
					<select name="extaddr" class="formfld">
238
						<option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>Interface address</option>
239
<?php					if (is_array($config['virtualip']['vip'])):
240
						foreach ($config['virtualip']['vip'] as $sn): ?>
241
						<option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['extaddr']) echo "selected"; ?>><?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?></option>
242
<?php					endforeach;
243
						endif; ?>
244
						<option value="any" <?php if($pconfig['extaddr'] == "any") echo "selected"; ?>>any</option>
245
					</select>
246
					<br />
247 5b237745 Scott Ullrich
                    <span class="vexpl">
248
					If you want this rule to apply to another IP address than the IP address of the interface chosen above,
249 1425e067 Bill Marquette
					select it here (you need to define <a href="firewall_virtual_ip.php">Virtual IP</a> addresses on the first).  Also note that if you are trying to redirect connections on the LAN select the "any" option.</span></td>
250 5b237745 Scott Ullrich
                </tr>
251 9ae40f2b Scott Ullrich
                <tr>
252 5b237745 Scott Ullrich
                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
253 9ae40f2b Scott Ullrich
                  <td width="78%" class="vtable">
254 b66f7667 Scott Ullrich
                    <select name="proto" class="formfld" onChange="proto_change();">
255 e598eab5 Scott Ullrich
                      <?php $protocols = explode(" ", "TCP UDP TCP/UDP GRE ESP"); foreach ($protocols as $proto): ?>
256 5b237745 Scott Ullrich
                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>><?=htmlspecialchars($proto);?></option>
257
                      <?php endforeach; ?>
258 9ae40f2b Scott Ullrich
                    </select> <br> <span class="vexpl">Choose which IP protocol
259 5b237745 Scott Ullrich
                    this rule should match.<br>
260
                    Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
261
                </tr>
262 9ae40f2b Scott Ullrich
                <tr>
263
                  <td width="22%" valign="top" class="vncellreq">External port
264 5b237745 Scott Ullrich
                    range </td>
265 9ae40f2b Scott Ullrich
                  <td width="78%" class="vtable">
266 5b237745 Scott Ullrich
                    <table border="0" cellspacing="0" cellpadding="0">
267 9ae40f2b Scott Ullrich
                      <tr>
268 5b237745 Scott Ullrich
                        <td>from:&nbsp;&nbsp;</td>
269
                        <td><select name="beginport" class="formfld" onChange="ext_rep_change();ext_change()">
270
                            <option value="">(other)</option>
271
                            <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
272
                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['beginport']) {
273 0e6998d1 Scott Ullrich
								echo "selected";
274
								$bfound = 1;
275
							}?>>
276 5b237745 Scott Ullrich
							<?=htmlspecialchars($wkportdesc);?>
277
							</option>
278
                            <?php endforeach; ?>
279 4ce8ac00 Erik Kristensen
                          </select> <input autocomplete='off' class="formfldalias" name="beginport_cust" id="beginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['beginport']; ?>"></td>
280 5b237745 Scott Ullrich
                      </tr>
281 9ae40f2b Scott Ullrich
                      <tr>
282 5b237745 Scott Ullrich
                        <td>to:</td>
283
                        <td><select name="endport" class="formfld" onChange="ext_change()">
284
                            <option value="">(other)</option>
285
                            <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
286
                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['endport']) {
287 0e6998d1 Scott Ullrich
								echo "selected";
288
								$bfound = 1;
289
							}?>>
290 5b237745 Scott Ullrich
							<?=htmlspecialchars($wkportdesc);?>
291
							</option>
292
							<?php endforeach; ?>
293 4ce8ac00 Erik Kristensen
                          </select> <input class="formfldalias"  autocomplete='off' name="endport_cust" id="endport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['endport']; ?>"></td>
294 5b237745 Scott Ullrich
                      </tr>
295
                    </table>
296 9ae40f2b Scott Ullrich
                    <br> <span class="vexpl">Specify the port or port range on
297 5b237745 Scott Ullrich
                    the firewall's external address for this mapping.<br>
298 9ae40f2b Scott Ullrich
                    Hint: you can leave the <em>'to'</em> field empty if you only
299 5b237745 Scott Ullrich
                    want to map a single port</span></td>
300
                </tr>
301 9ae40f2b Scott Ullrich
                <tr>
302 5b237745 Scott Ullrich
                  <td width="22%" valign="top" class="vncellreq">NAT IP</td>
303 9ae40f2b Scott Ullrich
                  <td width="78%" class="vtable">
304 4ce8ac00 Erik Kristensen
                    <input autocomplete='off' name="localip" type="text" class="formfldalias" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>">
305 9ae40f2b Scott Ullrich
                    <br> <span class="vexpl">Enter the internal IP address of
306 5b237745 Scott Ullrich
                    the server on which you want to map the ports.<br>
307
                    e.g. <em>192.168.1.12</em></span></td>
308
                </tr>
309 9ae40f2b Scott Ullrich
                <tr>
310 5b237745 Scott Ullrich
                  <td width="22%" valign="top" class="vncellreq">Local port</td>
311 9ae40f2b Scott Ullrich
                  <td width="78%" class="vtable">
312 5b237745 Scott Ullrich
                    <select name="localbeginport" class="formfld" onChange="ext_change()">
313
                      <option value="">(other)</option>
314
                      <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
315
                      <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['localbeginport']) {
316 0e6998d1 Scott Ullrich
							echo "selected";
317
							$bfound = 1;
318
						}?>>
319 5b237745 Scott Ullrich
					  <?=htmlspecialchars($wkportdesc);?>
320
					  </option>
321
                      <?php endforeach; ?>
322 4ce8ac00 Erik Kristensen
                    </select> <input  autocomplete='off' class="formfldalias" name="localbeginport_cust" id="localbeginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['localbeginport']; ?>">
323 5b237745 Scott Ullrich
                    <br>
324 9ae40f2b Scott Ullrich
                    <span class="vexpl">Specify the port on the machine with the
325
                    IP address entered above. In case of a port range, specify
326
                    the beginning port of the range (the end port will be calculated
327 5b237745 Scott Ullrich
                    automatically).<br>
328
                    Hint: this is usually identical to the 'from' port above</span></td>
329
                </tr>
330 9ae40f2b Scott Ullrich
                <tr>
331 5b237745 Scott Ullrich
                  <td width="22%" valign="top" class="vncell">Description</td>
332 9ae40f2b Scott Ullrich
                  <td width="78%" class="vtable">
333
                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
334
                    <br> <span class="vexpl">You may enter a description here
335 5b237745 Scott Ullrich
                    for your reference (not parsed).</span></td>
336 4a991889 Bill Marquette
                </tr><?php if ((!(isset($id) && $a_nat[$id])) || (isset($_GET['dup']))): ?>
337 9ae40f2b Scott Ullrich
                <tr>
338 5b237745 Scott Ullrich
                  <td width="22%" valign="top">&nbsp;</td>
339 9ae40f2b Scott Ullrich
                  <td width="78%">
340 5b237745 Scott Ullrich
                    <input name="autoadd" type="checkbox" id="autoadd" value="yes">
341 9ae40f2b Scott Ullrich
                    <strong>Auto-add a firewall rule to permit traffic through
342 5b237745 Scott Ullrich
                    this NAT rule</strong></td>
343
                </tr><?php endif; ?>
344 9ae40f2b Scott Ullrich
                <tr>
345 5b237745 Scott Ullrich
                  <td width="22%" valign="top">&nbsp;</td>
346 9ae40f2b Scott Ullrich
                  <td width="78%">
347 fc01e414 Scott Ullrich
                    <input name="Submit" type="submit" class="formbtn" value="Save"> <input type="button" class="formbtn" value="Cancel" onclick="history.back()">
348 5b237745 Scott Ullrich
                    <?php if (isset($id) && $a_nat[$id]): ?>
349 9ae40f2b Scott Ullrich
                    <input name="id" type="hidden" value="<?=$id;?>">
350 5b237745 Scott Ullrich
                    <?php endif; ?>
351
                  </td>
352
                </tr>
353
              </table>
354
</form>
355
<script language="JavaScript">
356
<!--
357 4ce8ac00 Erik Kristensen
	ext_change();
358 5b237745 Scott Ullrich
//-->
359
</script>
360 9ae40f2b Scott Ullrich
<?php
361
$isfirst = 0;
362
$aliases = "";
363
$addrisfirst = 0;
364
$aliasesaddr = "";
365 b964717d Scott Ullrich
if($config['aliases']['alias'] <> "")
366
	foreach($config['aliases']['alias'] as $alias_name) {
367
		if(!stristr($alias_name['address'], ".")) {
368
			if($isfirst == 1) $aliases .= ",";
369
			$aliases .= "'" . $alias_name['name'] . "'";
370
			$isfirst = 1;
371
		} else {
372
			if($addrisfirst == 1) $aliasesaddr .= ",";
373
			$aliasesaddr .= "'" . $alias_name['name'] . "'";
374
			$addrisfirst = 1;
375
		}
376 9ae40f2b Scott Ullrich
	}
377
?>
378
<script language="JavaScript">
379
<!--
380 4ce8ac00 Erik Kristensen
	var addressarray=new Array(<?php echo $aliasesaddr; ?>);
381
	var customarray=new Array(<?php echo $aliases; ?>);
382 9ae40f2b Scott Ullrich
//-->
383
</script>
384 5b237745 Scott Ullrich
<?php include("fend.inc"); ?>
385
</body>
386
</html>