Project

General

Profile

Download (17.9 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
			$config['filter']['rule'][] = $filterent;
203

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

    
213
				if($_POST['extaddr'] == "") {
214
					$filterent['destination']['network'] = "wanip";
215
				} else {
216
					$filterent['destination']['address'] = $_POST['extaddr'];
217
				}
218

    
219
				$dstpfrom = $_POST['localbeginport'];
220
				$dstpto = $dstpfrom + $_POST['endport'] - $_POST['beginport'];
221

    
222
				if ($dstpfrom == $dstpto)
223
					$filterent['destination']['port'] = $dstpfrom;
224
				else
225
					$filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
226

    
227
				$filterent['descr'] = "NAT " . $_POST['descr'];
228

    
229
				$config['filter']['rule'][] = $filterent;
230

    
231
				touch($d_filterconfdirty_path);
232

    
233
				write_config();
234

    
235
				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.");
236

    
237
				exit;
238

    
239
			}
240

    
241
			touch($d_filterconfdirty_path);
242
		}
243

    
244
		write_config();
245

    
246
		header("Location: firewall_nat.php");
247
		exit;
248
	}
249
}
250

    
251
$pgtitle = "Firewall: NAT: Port Forward: Edit";
252
include("head.inc");
253

    
254
?>
255

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