Project

General

Profile

Download (18.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	firewall_nat_edit.php
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	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

    
32
require("guiconfig.inc");
33

    
34
if (!is_array($config['nat']['rule'])) {
35
	$config['nat']['rule'] = array();
36
}
37
//nat_rules_sort();
38
$a_nat = &$config['nat']['rule'];
39

    
40
$id = $_GET['id'];
41
if (isset($_POST['id']))
42
	$id = $_POST['id'];
43

    
44
if (isset($_GET['dup'])) {
45
        $id = $_GET['dup'];
46
        $after = $_GET['dup'];
47
}
48

    
49
if (isset($id) && $a_nat[$id]) {
50
	$pconfig['extaddr'] = $a_nat[$id]['external-address'];
51
	$pconfig['proto'] = $a_nat[$id]['protocol'];
52
	list($pconfig['beginport'],$pconfig['endport']) = explode("-", $a_nat[$id]['external-port']);
53
	$pconfig['localip'] = $a_nat[$id]['target'];
54
	$pconfig['localbeginport'] = $a_nat[$id]['local-port'];
55
	$pconfig['descr'] = $a_nat[$id]['descr'];
56
	$pconfig['interface'] = $a_nat[$id]['interface'];
57
	$pconfig['nosync'] = isset($a_nat[$id]['nosync']);
58
	if (!$pconfig['interface'])
59
		$pconfig['interface'] = "wan";
60
} else {
61
	$pconfig['interface'] = "wan";
62
}
63

    
64
if (isset($_GET['dup']))
65
	unset($id);
66

    
67
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

    
76
	if (!$_POST['endport'])
77
		$_POST['endport'] = $_POST['beginport'];
78
        /* Make beginning port end port if not defined and endport is */
79
        if (!$_POST['beginport'] && $_POST['endport'])
80
                $_POST['beginport'] = $_POST['endport'];
81

    
82
	unset($input_errors);
83
	$pconfig = $_POST;
84

    
85
	/* input validation */
86
	if(strtoupper($_POST['proto']) == "TCP" or strtoupper($_POST['proto']) == "UDP" or strtoupper($_POST['proto']) == "TCP/UDP") {
87
		$reqdfields = explode(" ", "interface proto beginport endport localip localbeginport");
88
		$reqdfieldsn = explode(",", "Interface,Protocol,External port from,External port to,NAT IP,Local port");
89
	} else {
90
		$reqdfields = explode(" ", "interface proto localip");
91
		$reqdfieldsn = explode(",", "Interface,Protocol,NAT IP");
92
	}
93

    
94
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
95

    
96
	if (($_POST['localip'] && !is_ipaddroralias($_POST['localip']))) {
97
		$input_errors[] = "\"{$_POST['localip']}\" is not valid NAT IP address or host alias.";
98
	}
99

    
100
	/* only validate the ports if the protocol is TCP, UDP or TCP/UDP */
101
	if(strtoupper($_POST['proto']) == "TCP" or strtoupper($_POST['proto']) == "UDP" or strtoupper($_POST['proto']) == "TCP/UDP") {
102

    
103
		if (($_POST['beginport'] && !is_ipaddroralias($_POST['beginport']) && !is_port($_POST['beginport']))) {
104
			$input_errors[] = "The start port must be an integer between 1 and 65535.";
105
		}
106

    
107
		if (($_POST['endport'] && !is_ipaddroralias($_POST['endport']) && !is_port($_POST['endport']))) {
108
			$input_errors[] = "The end port must be an integer between 1 and 65535.";
109
		}
110

    
111
		if (($_POST['localbeginport'] && !is_ipaddroralias($_POST['localbeginport']) && !is_port($_POST['localbeginport']))) {
112
			$input_errors[] = "The local port must be an integer between 1 and 65535.";
113
		}
114

    
115
		if ($_POST['beginport'] > $_POST['endport']) {
116
			/* swap */
117
			$tmp = $_POST['endport'];
118
			$_POST['endport'] = $_POST['beginport'];
119
			$_POST['beginport'] = $tmp;
120
		}
121

    
122
		if (!$input_errors) {
123
			if (($_POST['endport'] - $_POST['beginport'] + $_POST['localbeginport']) > 65535)
124
				$input_errors[] = "The target port range must be an integer between 1 and 65535.";
125
		}
126

    
127
	}
128

    
129
	/* check for overlaps */
130
	foreach ($a_nat as $natent) {
131
		if (isset($id) && ($a_nat[$id]) && ($a_nat[$id] === $natent))
132
			continue;
133
		if ($natent['interface'] != $_POST['interface'])
134
			continue;
135
		if ($natent['external-address'] != $_POST['extaddr'])
136
			continue;
137
		if (($natent['proto'] != $_POST['proto']) && ($natent['proto'] != "tcp/udp") && ($_POST['proto'] != "tcp/udp"))
138
			continue;
139

    
140
		list($begp,$endp) = explode("-", $natent['external-port']);
141
		if (!$endp)
142
			$endp = $begp;
143

    
144
		if (!(   (($_POST['beginport'] < $begp) && ($_POST['endport'] < $begp))
145
		      || (($_POST['beginport'] > $endp) && ($_POST['endport'] > $endp)))) {
146

    
147
			$input_errors[] = "The external port range overlaps with an existing entry.";
148
			break;
149
		}
150
	}
151

    
152
	if (!$input_errors) {
153
		$natent = array();
154
		if ($_POST['extaddr'])
155
			$natent['external-address'] = $_POST['extaddr'];
156
		$natent['protocol'] = $_POST['proto'];
157

    
158
		if ($_POST['beginport'] == $_POST['endport'])
159
			$natent['external-port'] = $_POST['beginport'];
160
		else
161
			$natent['external-port'] = $_POST['beginport'] . "-" . $_POST['endport'];
162

    
163
		$natent['target'] = $_POST['localip'];
164
		$natent['local-port'] = $_POST['localbeginport'];
165
		$natent['interface'] = $_POST['interface'];
166
		$natent['descr'] = $_POST['descr'];
167

    
168
		if($_POST['nosync'] == "yes")
169
			$natent['nosync'] = true;
170
		else
171
			unset($natent['nosync']);
172

    
173
		if (isset($id) && $a_nat[$id])
174
			$a_nat[$id] = $natent;
175
		else {
176
			if (is_numeric($after))
177
				array_splice($a_nat, $after+1, 0, array($natent));
178
			else
179
				$a_nat[] = $natent;
180
		}
181

    
182
		touch($d_natconfdirty_path);
183

    
184
		if ($_POST['autoadd']) {
185
			/* auto-generate a matching firewall rule */
186
			$filterent = array();
187
			$filterent['interface'] = $_POST['interface'];
188
			$filterent['protocol'] = $_POST['proto'];
189
			$filterent['source']['any'] = "";
190
			$filterent['destination']['address'] = $_POST['localip'];
191

    
192
			$dstpfrom = $_POST['localbeginport'];
193
			$dstpto = $dstpfrom + $_POST['endport'] - $_POST['beginport'];
194

    
195
			if ($dstpfrom == $dstpto)
196
				$filterent['destination']['port'] = $dstpfrom;
197
			else
198
				$filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
199

    
200
			$filterent['descr'] = "NAT " . $_POST['descr'];
201
			/*
202
			 * Our firewall filter description may be no longer than
203
			 * 63 characters, so don't let it be.
204
			 */
205
			$filterent['descr'] = substr("NAT " . $_POST['descr'], 0, 63);
206

    
207
			$config['filter']['rule'][] = $filterent;
208

    
209
			/*    auto add rule to external port 21 as well since we are using
210
			 *    pftpx to help open up ports automatically
211
			 */
212
			if($_POST['endport'] == "21") {
213
				$filterent = array();
214
				$filterent['interface'] = $_POST['interface'];
215
				$filterent['protocol'] = $_POST['proto'];
216
				$filterent['source']['any'] = "";
217

    
218
				if($_POST['extaddr'] == "") {
219
					$filterent['destination']['network'] = "wanip";
220
				} else {
221
					$filterent['destination']['address'] = $_POST['extaddr'];
222
				}
223

    
224
				$dstpfrom = $_POST['localbeginport'];
225
				$dstpto = $dstpfrom + $_POST['endport'] - $_POST['beginport'];
226

    
227
				if ($dstpfrom == $dstpto)
228
					$filterent['destination']['port'] = $dstpfrom;
229
				else
230
					$filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
231

    
232
				$filterent['descr'] = "NAT " . $_POST['descr'];
233
				/* See comment above */
234
				$filterent['descr'] = substr("NAT " . $_POST['descr'], 0, 63);
235

    
236
				$config['filter']['rule'][] = $filterent;
237

    
238
				touch($d_filterconfdirty_path);
239

    
240
				write_config();
241

    
242
				header("Location: firewall_nat.php?savemsg=The%20changes%20have%20been%20saved.%20%20Please%20note%20that%20we%20have%20added%20an%20additional%20rule%20for%20the%20FTP%20helper.");
243

    
244
				exit;
245

    
246
			}
247

    
248
			touch($d_filterconfdirty_path);
249
		}
250

    
251
		write_config();
252

    
253
		header("Location: firewall_nat.php");
254
		exit;
255
	}
256
}
257

    
258
$pgtitle = "Firewall: NAT: Port Forward: Edit";
259
include("head.inc");
260

    
261
?>
262

    
263
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
264
<?php
265
include("fbegin.inc"); ?>
266
<p class="pgtitle"><?=$pgtitle?></p>
267
<?php if ($input_errors) print_input_errors($input_errors); ?>
268
            <form action="firewall_nat_edit.php" method="post" name="iform" id="iform">
269
              <table width="100%" border="0" cellpadding="6" cellspacing="0">
270
	  	<tr>
271
                  <td width="22%" valign="top" class="vncellreq">Interface</td>
272
                  <td width="78%" class="vtable">
273
					<select name="interface" class="formselect">
274
						<?php
275
						$interfaces = array('wan' => 'WAN', 'lan' => 'LAN', 'pptp' => 'PPTP', 'pppoe' => 'PPPOE');
276
						for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
277
							$interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
278
						}
279
						foreach ($interfaces as $iface => $ifacename): ?>
280
						<option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
281
						<?=htmlspecialchars($ifacename);?>
282
						</option>
283
						<?php endforeach; ?>
284
					</select><br>
285
                     <span class="vexpl">Choose which interface this rule applies to.<br>
286
                     Hint: in most cases, you'll want to use WAN here.</span></td>
287
                </tr>
288
			    <tr>
289
                  <td width="22%" valign="top" class="vncellreq">External address</td>
290
                  <td width="78%" class="vtable">
291
					<select name="extaddr" class="formselect">
292
						<option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>Interface address</option>
293
<?php					if (is_array($config['virtualip']['vip'])):
294
						foreach ($config['virtualip']['vip'] as $sn): ?>
295
						<option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['extaddr']) echo "selected"; ?>><?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?></option>
296
<?php					endforeach;
297
						endif; ?>
298
						<option value="any" <?php if($pconfig['extaddr'] == "any") echo "selected"; ?>>any</option>
299
					</select>
300
					<br />
301
                    <span class="vexpl">
302
					If you want this rule to apply to another IP address than the IP address of the interface chosen above,
303
					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>
304
                </tr>
305
                <tr>
306
                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
307
                  <td width="78%" class="vtable">
308
                    <select name="proto" class="formselect" onChange="proto_change(); check_for_aliases();">
309
                      <?php $protocols = explode(" ", "TCP UDP TCP/UDP GRE ESP"); foreach ($protocols as $proto): ?>
310
                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>><?=htmlspecialchars($proto);?></option>
311
                      <?php endforeach; ?>
312
                    </select> <br> <span class="vexpl">Choose which IP protocol
313
                    this rule should match.<br>
314
                    Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
315
                </tr>
316
                <tr>
317
                  <td width="22%" valign="top" class="vncellreq">External port
318
                    range </td>
319
                  <td width="78%" class="vtable">
320
                    <table border="0" cellspacing="0" cellpadding="0">
321
                      <tr>
322
                        <td>from:&nbsp;&nbsp;</td>
323
                        <td><select name="beginport" class="formselect" onChange="ext_rep_change(); ext_change(); check_for_aliases();">
324
                            <option value="">(other)</option>
325
                            <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
326
                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['beginport']) {
327
								echo "selected";
328
								$bfound = 1;
329
							}?>>
330
							<?=htmlspecialchars($wkportdesc);?>
331
							</option>
332
                            <?php endforeach; ?>
333
                          </select> <input onChange="check_for_aliases();" autocomplete='off' class="formfldalias" name="beginport_cust" id="beginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['beginport']; ?>"></td>
334
                      </tr>
335
                      <tr>
336
                        <td>to:</td>
337
                        <td><select name="endport" class="formselect" onChange="ext_change(); check_for_aliases();">
338
                            <option value="">(other)</option>
339
                            <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
340
                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['endport']) {
341
								echo "selected";
342
								$bfound = 1;
343
							}?>>
344
							<?=htmlspecialchars($wkportdesc);?>
345
							</option>
346
							<?php endforeach; ?>
347
                          </select> <input onChange="check_for_aliases();" class="formfldalias" autocomplete='off' name="endport_cust" id="endport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['endport']; ?>"></td>
348
                      </tr>
349
                    </table>
350
                    <br> <span class="vexpl">Specify the port or port range on
351
                    the firewall's external address for this mapping.<br>
352
                    Hint: you can leave the <em>'to'</em> field empty if you only
353
                    want to map a single port</span></td>
354
                </tr>
355
                <tr>
356
                  <td width="22%" valign="top" class="vncellreq">NAT IP</td>
357
                  <td width="78%" class="vtable">
358
                    <input autocomplete='off' name="localip" type="text" class="formfldalias" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>">
359
                    <br> <span class="vexpl">Enter the internal IP address of
360
                    the server on which you want to map the ports.<br>
361
                    e.g. <em>192.168.1.12</em></span></td>
362
                </tr>
363
                <tr>
364
                  <td width="22%" valign="top" class="vncellreq">Local port</td>
365
                  <td width="78%" class="vtable">
366
                    <select name="localbeginport" class="formselect" onChange="ext_change();check_for_aliases();">
367
                      <option value="">(other)</option>
368
                      <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
369
                      <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['localbeginport']) {
370
							echo "selected";
371
							$bfound = 1;
372
						}?>>
373
					  <?=htmlspecialchars($wkportdesc);?>
374
					  </option>
375
                      <?php endforeach; ?>
376
                    </select> <input onChange="check_for_aliases();" autocomplete='off' class="formfldalias" name="localbeginport_cust" id="localbeginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['localbeginport']; ?>">
377
                    <br>
378
                    <span class="vexpl">Specify the port on the machine with the
379
                    IP address entered above. In case of a port range, specify
380
                    the beginning port of the range (the end port will be calculated
381
                    automatically).<br>
382
                    Hint: this is usually identical to the 'from' port above</span></td>
383
                </tr>
384
                <tr>
385
                  <td width="22%" valign="top" class="vncell">Description</td>
386
                  <td width="78%" class="vtable">
387
                    <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
388
                    <br> <span class="vexpl">You may enter a description here
389
                    for your reference (not parsed).</span></td>
390
                </tr>
391
				<tr>
392
					<td width="22%" valign="top" class="vncell">No XMLRPC Sync</td>
393
					<td width="78%" class="vtable">
394
						<input type="checkbox" value="yes" name="nosync"<?php if($pconfig['nosync']) echo " CHECKED"; ?>><br>
395
						HINT: This prevents the rule from automatically syncing to other CARP members.
396
					</td>
397
				</tr>
398
                <?php if ((!(isset($id) && $a_nat[$id])) || (isset($_GET['dup']))): ?>
399
                <tr>
400
                  <td width="22%" valign="top">&nbsp;</td>
401
                  <td width="78%">
402
                    <input name="autoadd" type="checkbox" id="autoadd" value="yes" CHECKED>
403
                    <strong>Auto-add a firewall rule to permit traffic through
404
                    this NAT rule</strong></td>
405
                </tr><?php endif; ?>
406
                <tr>
407
                  <td width="22%" valign="top">&nbsp;</td>
408
                  <td width="78%">
409
                    <input name="Submit" type="submit" class="formbtn" value="Save"> <input type="button" class="formbtn" value="Cancel" onclick="history.back()">
410
                    <?php if (isset($id) && $a_nat[$id]): ?>
411
                    <input name="id" type="hidden" value="<?=$id;?>">
412
                    <?php endif; ?>
413
                  </td>
414
                </tr>
415
              </table>
416
</form>
417
<script language="JavaScript">
418
<!--
419
	ext_change();
420
//-->
421
</script>
422
<?php
423
$isfirst = 0;
424
$aliases = "";
425
$addrisfirst = 0;
426
$aliasesaddr = "";
427
if($config['aliases']['alias'] <> "")
428
	foreach($config['aliases']['alias'] as $alias_name) {
429
		if(!stristr($alias_name['address'], ".")) {
430
			if($isfirst == 1) $aliases .= ",";
431
			$aliases .= "'" . $alias_name['name'] . "'";
432
			$isfirst = 1;
433
		} else {
434
			if($addrisfirst == 1) $aliasesaddr .= ",";
435
			$aliasesaddr .= "'" . $alias_name['name'] . "'";
436
			$addrisfirst = 1;
437
		}
438
	}
439
?>
440
<script language="JavaScript">
441
<!--
442
	var addressarray=new Array(<?php echo $aliasesaddr; ?>);
443
	var customarray=new Array(<?php echo $aliases; ?>);
444
//-->
445
</script>
446
<?php include("fend.inc"); ?>
447
</body>
448
</html>
(45-45/186)