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. (and take "NAT "
204
			 * into account)
205
			 */
206
			$filterent['descr'] = substr("NAT " . $_POST['descr'], 0, 59);
207

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

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

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

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

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

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

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

    
239
				touch($d_filterconfdirty_path);
240

    
241
				write_config();
242

    
243
				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.");
244

    
245
				exit;
246

    
247
			}
248

    
249
			touch($d_filterconfdirty_path);
250
		}
251

    
252
		write_config();
253

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

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

    
262
?>
263

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