Project

General

Profile

Download (36 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
	pfSense_MODULE:	nat
33
*/
34

    
35
##|+PRIV
36
##|*IDENT=page-firewall-nat-portforward-edit
37
##|*NAME=Firewall: NAT: Port Forward: Edit page
38
##|*DESCR=Allow access to the 'Firewall: NAT: Port Forward: Edit' page.
39
##|*MATCH=firewall_nat_edit.php*
40
##|-PRIV
41

    
42
require("guiconfig.inc");
43
require_once("itemid.inc");
44
require("filter.inc");
45
require("shaper.inc");
46

    
47
$specialsrcdst = explode(" ", "any pptp pppoe l2tp openvpn");
48
$ifdisp = get_configured_interface_with_descr();
49
foreach ($ifdisp as $kif => $kdescr) {
50
	$specialsrcdst[] = "{$kif}";
51
	$specialsrcdst[] = "{$kif}ip";
52
}
53

    
54
if (!is_array($config['nat']['rule'])) {
55
	$config['nat']['rule'] = array();
56
}
57
$a_nat = &$config['nat']['rule'];
58

    
59
$id = $_GET['id'];
60
if (isset($_POST['id']))
61
	$id = $_POST['id'];
62

    
63
if (isset($_GET['dup'])) {
64
        $id = $_GET['dup'];
65
        $after = $_GET['dup'];
66
}
67

    
68
if (isset($id) && $a_nat[$id]) {
69
	$pconfig['disabled'] = isset($a_nat[$id]['disabled']);
70
	$pconfig['nordr'] = isset($a_nat[$id]['nordr']);
71

    
72
	address_to_pconfig($a_nat[$id]['source'], $pconfig['src'],
73
		$pconfig['srcmask'], $pconfig['srcnot'],
74
		$pconfig['srcbeginport'], $pconfig['srcendport']);
75

    
76
	address_to_pconfig($a_nat[$id]['destination'], $pconfig['dst'],
77
		$pconfig['dstmask'], $pconfig['dstnot'],
78
		$pconfig['dstbeginport'], $pconfig['dstendport']);
79

    
80
	$pconfig['proto'] = $a_nat[$id]['protocol'];
81
	$pconfig['localip'] = $a_nat[$id]['target'];
82
	$pconfig['localbeginport'] = $a_nat[$id]['local-port'];
83
	$pconfig['descr'] = $a_nat[$id]['descr'];
84
	$pconfig['interface'] = $a_nat[$id]['interface'];
85
	$pconfig['associated-rule-id'] = $a_nat[$id]['associated-rule-id'];
86
	$pconfig['nosync'] = isset($a_nat[$id]['nosync']);
87

    
88
	if (!$pconfig['interface'])
89
		$pconfig['interface'] = "wan";
90
} else {
91
	$pconfig['interface'] = "wan";
92
	$pconfig['src'] = "any";
93
	$pconfig['srcbeginport'] = "any";
94
	$pconfig['srcendport'] = "any";
95
}
96

    
97
if (isset($_GET['dup']))
98
	unset($id);
99

    
100
/*  run through $_POST items encoding HTML entties so that the user
101
 *  cannot think he is slick and perform a XSS attack on the unwilling
102
 */
103
foreach ($_POST as $key => $value) {
104
	$temp = $value;
105
	$newpost = htmlentities($temp);
106
	if($newpost <> $temp)
107
		$input_errors[] = "Invalid characters detected ($temp).  Please remove invalid characters and save again.";
108
}
109

    
110
if ($_POST) {
111

    
112
	if(strtoupper($_POST['proto']) == "TCP" || strtoupper($_POST['proto']) == "UDP" || strtoupper($_POST['proto']) == "TCP/UDP") {
113
		if ($_POST['srcbeginport_cust'] && !$_POST['srcbeginport'])
114
			$_POST['srcbeginport'] = $_POST['srcbeginport_cust'];
115
		if ($_POST['srcendport_cust'] && !$_POST['srcendport'])
116
			$_POST['srcendport'] = $_POST['srcendport_cust'];
117

    
118
		if ($_POST['srcbeginport'] == "any") {
119
			$_POST['srcbeginport'] = 0;
120
			$_POST['srcendport'] = 0;
121
		} else {
122
			if (!$_POST['srcendport'])
123
				$_POST['srcendport'] = $_POST['srcbeginport'];
124
		}
125
		if ($_POST['srcendport'] == "any")
126
			$_POST['srcendport'] = $_POST['srcbeginport'];
127

    
128
		if ($_POST['dstbeginport_cust'] && !$_POST['dstbeginport'])
129
			$_POST['dstbeginport'] = $_POST['dstbeginport_cust'];
130
		if ($_POST['dstendport_cust'] && !$_POST['dstendport'])
131
			$_POST['dstendport'] = $_POST['dstendport_cust'];
132

    
133
		if ($_POST['dstbeginport'] == "any") {
134
			$_POST['dstbeginport'] = 0;
135
			$_POST['dstendport'] = 0;
136
		} else {
137
			if (!$_POST['dstendport'])
138
				$_POST['dstendport'] = $_POST['dstbeginport'];
139
		}
140
		if ($_POST['dstendport'] == "any")
141
			$_POST['dstendport'] = $_POST['dstbeginport'];
142

    
143
		if ($_POST['localbeginport_cust'] && !$_POST['localbeginport'])
144
			$_POST['localbeginport'] = $_POST['localbeginport_cust'];
145

    
146
		/* Make beginning port end port if not defined and endport is */
147
		if (!$_POST['srcbeginport'] && $_POST['srcendport'])
148
			$_POST['srcbeginport'] = $_POST['srcendport'];
149
		if (!$_POST['dstbeginport'] && $_POST['dstendport'])
150
			$_POST['dstbeginport'] = $_POST['dstendport'];
151
	} else {
152
		$_POST['srcbeginport'] = 0;
153
		$_POST['srcendport'] = 0;
154
		$_POST['dstbeginport'] = 0;
155
		$_POST['dstendport'] = 0;
156
	}
157

    
158
	if (is_specialnet($_POST['srctype'])) {
159
		$_POST['src'] = $_POST['srctype'];
160
		$_POST['srcmask'] = 0;
161
	} else if ($_POST['srctype'] == "single") {
162
		$_POST['srcmask'] = 32;
163
	}
164
	if (is_specialnet($_POST['dsttype'])) {
165
		$_POST['dst'] = $_POST['dsttype'];
166
		$_POST['dstmask'] = 0;
167
	} else if ($_POST['dsttype'] == "single") {
168
		$_POST['dstmask'] = 32;
169
	} else if (is_ipaddr($_POST['dsttype'])) {
170
		$_POST['dst'] = $_POST['dsttype'];
171
		$_POST['dstmask'] = 32;
172
		$_POST['dsttype'] = "single";
173
	}
174

    
175
	unset($input_errors);
176
	$pconfig = $_POST;
177

    
178
	/* input validation */
179
	if(strtoupper($_POST['proto']) == "TCP" or strtoupper($_POST['proto']) == "UDP" or strtoupper($_POST['proto']) == "TCP/UDP") {
180
		$reqdfields = explode(" ", "interface proto dstbeginport dstendport localip");
181
		$reqdfieldsn = explode(",", "Interface,Protocol,Destination port from,Destination port to,NAT IP");
182
	} else {
183
		$reqdfields = explode(" ", "interface proto localip");
184
		$reqdfieldsn = explode(",", "Interface,Protocol,NAT IP");
185
	}
186

    
187
	if ($_POST['srctype'] == "single" || $_POST['srctype'] == "network") {
188
		$reqdfields[] = "src";
189
		$reqdfieldsn[] = "Source address";
190
	}
191
	if ($_POST['dsttype'] == "single" || $_POST['dsttype'] == "network") {
192
		$reqdfields[] = "dst";
193
		$reqdfieldsn[] = "Destination address";
194
	}
195

    
196
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
197

    
198
	if (!$_POST['srcbeginport']) {
199
		$_POST['srcbeginport'] = 0;
200
		$_POST['srcendport'] = 0;
201
	}
202
	if (!$_POST['dstbeginport']) {
203
		$_POST['dstbeginport'] = 0;
204
		$_POST['dstendport'] = 0;
205
	}
206

    
207
	if (($_POST['localip'] && !is_ipaddroralias($_POST['localip']))) {
208
		$input_errors[] = "\"{$_POST['localip']}\" is not valid NAT IP address or host alias.";
209
	}
210

    
211
	if ($_POST['srcbeginport'] && !is_portoralias($_POST['srcbeginport']))
212
		$input_errors[] = "{$_POST['srcbeginport']} is not a valid start source port. It must be a port alias or integer between 1 and 65535.";
213
	if ($_POST['srcendport'] && !is_portoralias($_POST['srcendport']))
214
		$input_errors[] = "{$_POST['srcendport']} is not a valid end source port. It must be a port alias or integer between 1 and 65535.";
215
	if ($_POST['dstbeginport'] && !is_portoralias($_POST['dstbeginport']))
216
		$input_errors[] = "{$_POST['dstbeginport']} is not a valid start destination port. It must be a port alias or integer between 1 and 65535.";
217
	if ($_POST['dstendport'] && !is_portoralias($_POST['dstendport']))
218
		$input_errors[] = "{$_POST['dstendport']} is not a valid end destination port. It must be a port alias or integer between 1 and 65535.";
219

    
220
	if ($_POST['localbeginport'] && !is_portoralias($_POST['localbeginport'])) {
221
		$input_errors[] = "{$_POST['localbeginport']} is not a valid local port. It must be a port alias or integer between 1 and 65535.";
222
	}
223

    
224
	/* if user enters an alias and selects "network" then disallow. */
225
	if( ($_POST['srctype'] == "network" && is_alias($_POST['src']) ) 
226
	 || ($_POST['dsttype'] == "network" && is_alias($_POST['dst']) ) ) {
227
		$input_errors[] = "You must specify single host or alias for alias entries.";
228
	}
229

    
230
	if (!is_specialnet($_POST['srctype'])) {
231
		if (($_POST['src'] && !is_ipaddroralias($_POST['src']))) {
232
			$input_errors[] = "{$_POST['src']} is not a valid source IP address or alias.";
233
		}
234
		if (($_POST['srcmask'] && !is_numericint($_POST['srcmask']))) {
235
			$input_errors[] = "A valid source bit count must be specified.";
236
		}
237
	}
238
	if (!is_specialnet($_POST['dsttype'])) {
239
		if (($_POST['dst'] && !is_ipaddroralias($_POST['dst']))) {
240
			$input_errors[] = "{$_POST['dst']} is not a valid destination IP address or alias.";
241
		}
242
		if (($_POST['dstmask'] && !is_numericint($_POST['dstmask']))) {
243
			$input_errors[] = "A valid destination bit count must be specified.";
244
		}
245
	}
246

    
247
	if ($_POST['srcbeginport'] > $_POST['srcendport']) {
248
		/* swap */
249
		$tmp = $_POST['srcendport'];
250
		$_POST['srcendport'] = $_POST['srcbeginport'];
251
		$_POST['srcbeginport'] = $tmp;
252
	}
253
	if ($_POST['dstbeginport'] > $_POST['dstendport']) {
254
		/* swap */
255
		$tmp = $_POST['dstendport'];
256
		$_POST['dstendport'] = $_POST['dstbeginport'];
257
		$_POST['dstbeginport'] = $tmp;
258
	}
259

    
260
	if (!$input_errors) {
261
		if (($_POST['dstendport'] - $_POST['dstbeginport'] + $_POST['localbeginport']) > 65535)
262
			$input_errors[] = "The target port range must be an integer between 1 and 65535.";
263
	}
264

    
265
	/* check for overlaps */
266
	foreach ($a_nat as $natent) {
267
		if (isset($id) && ($a_nat[$id]) && ($a_nat[$id] === $natent))
268
			continue;
269
		if ($natent['interface'] != $_POST['interface'])
270
			continue;
271
		if ($natent['destination']['address'] != $_POST['dst'])
272
			continue;
273
		if (($natent['proto'] != $_POST['proto']) && ($natent['proto'] != "tcp/udp") && ($_POST['proto'] != "tcp/udp"))
274
			continue;
275

    
276
		list($begp,$endp) = explode("-", $natent['destination']['port']);
277
		if (!$endp)
278
			$endp = $begp;
279

    
280
		if (!(   (($_POST['beginport'] < $begp) && ($_POST['endport'] < $begp))
281
		      || (($_POST['beginport'] > $endp) && ($_POST['endport'] > $endp)))) {
282

    
283
			$input_errors[] = "The destination port range overlaps with an existing entry.";
284
			break;
285
		}
286
	}
287

    
288
	if (!$input_errors) {
289
		$natent = array();
290

    
291
		$natent['disabled'] = isset($_POST['disabled']) ? true:false;
292
		$natent['nordr'] = isset($_POST['nordr']) ? true:false;
293

    
294
		pconfig_to_address($natent['source'], $_POST['src'],
295
			$_POST['srcmask'], $_POST['srcnot'],
296
			$_POST['srcbeginport'], $_POST['srcendport']);
297

    
298
		pconfig_to_address($natent['destination'], $_POST['dst'],
299
			$_POST['dstmask'], $_POST['dstnot'],
300
			$_POST['dstbeginport'], $_POST['dstendport']);
301

    
302
		$natent['protocol'] = $_POST['proto'];
303

    
304
		$natent['target'] = $_POST['localip'];
305
		$natent['local-port'] = $_POST['localbeginport'];
306
		$natent['interface'] = $_POST['interface'];
307
		$natent['descr'] = $_POST['descr'];
308
		$natent['associated-rule-id'] = $_POST['associated-rule-id'];
309

    
310
		if($_POST['filter-rule-association'] == "pass")
311
			$natent['associated-rule-id'] = "pass";
312

    
313
		if($_POST['nosync'] == "yes")
314
			$natent['nosync'] = true;
315
		else
316
			unset($natent['nosync']);
317

    
318
		// If we used to have an associated filter rule, but no-longer should have one
319
		if (!empty($a_nat[$id]) && ( empty($natent['associated-rule-id']) || $natent['associated-rule-id'] != $a_nat[$id]['associated-rule-id'] ) ) {
320
			// Delete the previous rule
321
			delete_id($a_nat[$id]['associated-rule-id'], $config['filter']['rule']);
322
			mark_subsystem_dirty('filter');
323
		}
324

    
325
		$need_filter_rule = false;
326
		// Updating a rule with a filter rule associated
327
		if (!empty($natent['associated-rule-id']))
328
			$need_filter_rule = true;
329
		// Create a rule or if we want to create a new one
330
		if( $natent['associated-rule-id']=='new' ) {
331
			$need_filter_rule = true;
332
			unset( $natent['associated-rule-id'] );
333
			$_POST['filter-rule-association']='add-associated';
334
		}
335
		// If creating a new rule, where we want to add the filter rule, associated or not
336
		else if( isset($_POST['filter-rule-association']) &&
337
			($_POST['filter-rule-association']=='add-associated' ||
338
			$_POST['filter-rule-association']=='add-unassociated') )
339
			$need_filter_rule = true;
340

    
341
		// Determine NAT entry ID now, we need it for the firewall rule
342
		if (isset($id) && $a_nat[$id])
343
			$a_nat[$id] = $natent;
344
		else {
345
			if (is_numeric($after))
346
				$id = $after + 1;
347
			else
348
				$id = count($a_nat);
349
		}
350

    
351
		if ($need_filter_rule == true) {
352

    
353
			/* auto-generate a matching firewall rule */
354
			$filterent = array();
355
			unset($filterentid);
356
			// If a rule already exists, load it
357
			if (!empty($natent['associated-rule-id'])) {
358
				$filterentid = get_id($natent['associated-rule-id'], $config['filter']['rule']);
359
				if ($filterentid == false) {
360
					pconfig_to_address($filterent['source'], $_POST['src'],
361
						$_POST['srcmask'], $_POST['srcnot'],
362
						$_POST['srcbeginport'], $_POST['srcendport']);
363
					$filterent['associated-rule-id'] = $natent['associated-rule-id'];
364
				} else
365
					$filterent =& $config['filter']['rule'][$filterentid];
366
			} else
367
				pconfig_to_address($filterent['source'], $_POST['src'],
368
					$_POST['srcmask'], $_POST['srcnot'],
369
					$_POST['srcbeginport'], $_POST['srcendport']);
370

    
371
			// Update interface, protocol and destination
372
			$filterent['interface'] = $_POST['interface'];
373
			$filterent['protocol'] = $_POST['proto'];
374
			$filterent['destination']['address'] = $_POST['localip'];
375

    
376
			$dstpfrom = $_POST['localbeginport'];
377
			$dstpto = $dstpfrom + $_POST['dstendport'] - $_POST['dstbeginport'];
378

    
379
			if ($dstpfrom == $dstpto)
380
				$filterent['destination']['port'] = $dstpfrom;
381
			else
382
				$filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
383

    
384
			/*
385
			 * Our firewall filter description may be no longer than
386
			 * 63 characters, so don't let it be.
387
			 */
388
			$filterent['descr'] = substr("NAT " . $_POST['descr'], 0, 62);
389

    
390
			// If this is a new rule, create an ID and add the rule
391
			if( $_POST['filter-rule-association']=='add-associated' ) {
392
				$filterent['associated-rule-id'] = $natent['associated-rule-id'] = get_unique_id();
393
				$config['filter']['rule'][] = $filterent;
394
			}
395

    
396
			mark_subsystem_dirty('filter');
397
		}
398

    
399
		// Update the NAT entry now
400
		if (isset($id) && $a_nat[$id])
401
			$a_nat[$id] = $natent;
402
		else {
403
			if (is_numeric($after))
404
				array_splice($a_nat, $after+1, 0, array($natent));
405
			else
406
				$a_nat[] = $natent;
407
		}
408

    
409
		mark_subsystem_dirty('natconf');
410

    
411
		write_config();
412

    
413
		header("Location: firewall_nat.php");
414
		exit;
415
	}
416
}
417

    
418
$pgtitle = array("Firewall","NAT","Port Forward: Edit");
419
include("head.inc");
420

    
421
?>
422

    
423
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
424
<?php
425
include("fbegin.inc"); ?>
426
<?php if ($input_errors) print_input_errors($input_errors); ?>
427
            <form action="firewall_nat_edit.php" method="post" name="iform" id="iform">
428
              <table width="100%" border="0" cellpadding="6" cellspacing="0">
429
				<tr>
430
					<td colspan="2" valign="top" class="listtopic">Edit Redirect entry</td>
431
				</tr>
432
		<tr>
433
			<td width="22%" valign="top" class="vncellreq">Disabled</td>
434
			<td width="78%" class="vtable">
435
				<input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
436
				<strong>Disable this rule</strong><br />
437
				<span class="vexpl">Set this option to disable this rule without removing it from the list.</span>
438
			</td>
439
		</tr>
440
                <tr>
441
                  <td width="22%" valign="top" class="vncell">No RDR (NOT)</td>
442
                  <td width="78%" class="vtable">
443
                    <input type="checkbox" name="nordr"<?php if($pconfig['nordr']) echo " CHECKED"; ?>>
444
                    <span class="vexpl">Enabling this option will disable redirection for traffic matching this rule.
445
                    <br>Hint: this option is rarely needed, don't use this unless you know what you're doing.</span>
446
                  </td>
447
                </tr>
448
		<tr>
449
                  <td width="22%" valign="top" class="vncellreq">Interface</td>
450
                  <td width="78%" class="vtable">
451
					<select name="interface" class="formselect" onChange="dst_change(this.value,iface_old,document.iform.dsttype.value);iface_old = document.iform.interface.value;typesel_change();">
452
						<?php
453

    
454
						$iflist = get_configured_interface_with_descr(false, true);
455
						foreach ($iflist as $if => $ifdesc)
456
							if(have_ruleint_access($if))
457
								$interfaces[$if] = $ifdesc;
458

    
459
						if ($config['pptpd']['mode'] == "server")
460
							if(have_ruleint_access("pptp"))
461
								$interfaces['pptp'] = "PPTP VPN";
462

    
463
						if ($config['pppoe']['mode'] == "server")
464
							if(have_ruleint_access("pppoe"))
465
								$interfaces['pppoe'] = "PPPoE VPN";
466

    
467
						/* add ipsec interfaces */
468
						if (isset($config['ipsec']['enable']) || isset($config['ipsec']['mobileclients']['enable']))
469
							if(have_ruleint_access("enc0"))
470
								$interfaces["enc0"] = "IPsec";
471

    
472
						foreach ($interfaces as $iface => $ifacename): ?>
473
						<option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
474
						<?=htmlspecialchars($ifacename);?>
475
						</option>
476
						<?php endforeach; ?>
477
					</select><br>
478
                     <span class="vexpl">Choose which interface this rule applies to.<br>
479
                     Hint: in most cases, you'll want to use WAN here.</span></td>
480
                </tr>
481
                <tr>
482
                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
483
                  <td width="78%" class="vtable">
484
                    <select name="proto" class="formselect" onChange="proto_change(); check_for_aliases();">
485
                      <?php $protocols = explode(" ", "TCP UDP TCP/UDP GRE ESP"); foreach ($protocols as $proto): ?>
486
                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>><?=htmlspecialchars($proto);?></option>
487
                      <?php endforeach; ?>
488
                    </select> <br> <span class="vexpl">Choose which IP protocol
489
                    this rule should match.<br>
490
                    Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
491
                </tr>
492
		<tr id="showadvancedboxsrc" name="showadvancedboxsrc">
493
			<td width="22%" valign="top" class="vncellreq">Source</td>
494
			<td width="78%" class="vtable">
495
				<input type="button" onClick="show_source()" value="Advanced"></input> - Show source address and port range</a>
496
			</td>
497
		</tr>
498
		<tr style="display: none;" id="srctable" name="srctable">
499
			<td width="22%" valign="top" class="vncellreq">Source</td>
500
			<td width="78%" class="vtable">
501
				<input name="srcnot" type="checkbox" id="srcnot" value="yes" <?php if ($pconfig['srcnot']) echo "checked"; ?>>
502
				<strong>not</strong>
503
				<br />
504
				Use this option to invert the sense of the match.
505
				<br />
506
				<br />
507
				<table border="0" cellspacing="0" cellpadding="0">
508
					<tr>
509
						<td>Type:&nbsp;&nbsp;</td>
510
						<td>
511
							<select name="srctype" class="formselect" onChange="typesel_change()">
512
<?php
513
								$sel = is_specialnet($pconfig['src']); ?>
514
								<option value="any"     <?php if ($pconfig['src'] == "any") { echo "selected"; } ?>>any</option>
515
								<option value="single"  <?php if (($pconfig['srcmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>Single host or alias</option>
516
								<option value="network" <?php if (!$sel) echo "selected"; ?>>Network</option>
517
								<?php if(have_ruleint_access("pptp")): ?>
518
								<option value="pptp"    <?php if ($pconfig['src'] == "pptp") { echo "selected"; } ?>>PPTP clients</option>
519
								<?php endif; ?>
520
								<?php if(have_ruleint_access("pppoe")): ?>
521
								<option value="pppoe"   <?php if ($pconfig['src'] == "pppoe") { echo "selected"; } ?>>PPPoE clients</option>
522
								<?php endif; ?>
523
								 <?php if(have_ruleint_access("l2tp")): ?>
524
                                                                <option value="l2tp"   <?php if ($pconfig['src'] == "l2tp") { echo "selected"; } ?>>L2TP clients</option>
525
                                                                <?php endif; ?>
526
<?php
527
								foreach ($ifdisp as $ifent => $ifdesc): ?>
528
								<?php if(have_ruleint_access($ifent)): ?>
529
									<option value="<?=$ifent;?>" <?php if ($pconfig['src'] == $ifent) { echo "selected"; } ?>><?=htmlspecialchars($ifdesc);?> subnet</option>
530
									<option value="<?=$ifent;?>ip"<?php if ($pconfig['src'] ==  $ifent . "ip") { echo "selected"; } ?>>
531
										<?=$ifdesc?> address
532
									</option>
533
								<?php endif; ?>
534
<?php 							endforeach; ?>
535
							</select>
536
						</td>
537
					</tr>
538
					<tr>
539
						<td>Address:&nbsp;&nbsp;</td>
540
						<td>
541
							<input autocomplete='off' name="src" type="text" class="formfldalias" id="src" size="20" value="<?php if (!is_specialnet($pconfig['src'])) echo htmlspecialchars($pconfig['src']);?>"> /
542
							<select name="srcmask" class="formselect" id="srcmask">
543
<?php						for ($i = 31; $i > 0; $i--): ?>
544
								<option value="<?=$i;?>" <?php if ($i == $pconfig['srcmask']) echo "selected"; ?>><?=$i;?></option>
545
<?php 						endfor; ?>
546
							</select>
547
						</td>
548
					</tr>
549
				</table>
550
			</td>
551
		</tr>
552
		<tr style="display:none" id="sprtable" name="sprtable">
553
			<td width="22%" valign="top" class="vncellreq">Source port range</td>
554
			<td width="78%" class="vtable">
555
				<table border="0" cellspacing="0" cellpadding="0">
556
					<tr>
557
						<td>from:&nbsp;&nbsp;</td>
558
						<td>
559
							<select name="srcbeginport" class="formselect" onchange="src_rep_change();ext_change()">
560
								<option value="">(other)</option>
561
								<option value="any" <?php $bfound = 0; if ($pconfig['srcbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
562
<?php 							foreach ($wkports as $wkport => $wkportdesc): ?>
563
									<option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcbeginport']) { echo "selected"; $bfound = 1; } ?>><?=htmlspecialchars($wkportdesc);?></option>
564
<?php 							endforeach; ?>
565
							</select>
566
							<input autocomplete='off' class="formfldalias" name="srcbeginport_cust" id="srcbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcbeginport']) echo $pconfig['srcbeginport']; ?>">
567
						</td>
568
					</tr>
569
					<tr>
570
						<td>to:</td>
571
						<td>
572
							<select name="srcendport" class="formselect" onchange="ext_change()">
573
								<option value="">(other)</option>
574
								<option value="any" <?php $bfound = 0; if ($pconfig['srcendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
575
<?php							foreach ($wkports as $wkport => $wkportdesc): ?>
576
									<option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcendport']) { echo "selected"; $bfound = 1; } ?>><?=htmlspecialchars($wkportdesc);?></option>
577
<?php							endforeach; ?>
578
							</select>
579
							<input autocomplete='off' class="formfldalias" name="srcendport_cust" id="srcendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcendport']) echo $pconfig['srcendport']; ?>">
580
						</td>
581
					</tr>
582
				</table>
583
				<br />
584
				<span class="vexpl"><?=gettext("Specify the source port or port range for this rule. <b>This is usually <em>random</em> and almost never equal to the destination port range (and should usually be &quot;any&quot;).</b> <br /> Hint: you can leave the <em>'to'</em> field empty if you only want to filter a single port.");?></span><br/>
585
			</td>
586
		</tr>
587
		<tr>
588
			<td width="22%" valign="top" class="vncellreq">Destination</td>
589
			<td width="78%" class="vtable">
590
				<input name="dstnot" type="checkbox" id="dstnot" value="yes" <?php if ($pconfig['dstnot']) echo "checked"; ?>>
591
				<strong>not</strong>
592
					<br />
593
				Use this option to invert the sense of the match.
594
					<br />
595
					<br />
596
				<table border="0" cellspacing="0" cellpadding="0">
597
					<tr>
598
						<td>Type:&nbsp;&nbsp;</td>
599
						<td>
600
							<select name="dsttype" class="formselect" onChange="typesel_change()">
601
<?php
602
								$sel = is_specialnet($pconfig['dst']); ?>
603
								<option value="any" <?php if ($pconfig['dst'] == "any") { echo "selected"; } ?>>any</option>
604
								<option value="single" <?php if (($pconfig['dstmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>Single host or alias</option>
605
								<option value="network" <?php if (!$sel) echo "selected"; ?>>Network</option>
606
								<?php if(have_ruleint_access("pptp")): ?>
607
								<option value="pptp" <?php if ($pconfig['dst'] == "pptp") { echo "selected"; } ?>>PPTP clients</option>
608
								<?php endif; ?>
609
								<?php if(have_ruleint_access("pppoe")): ?>
610
								<option value="pppoe" <?php if ($pconfig['dst'] == "pppoe") { echo "selected"; } ?>>PPPoE clients</option>
611
								<?php endif; ?>
612
								<?php if(have_ruleint_access("l2tp")): ?>
613
                                                                <option value="l2tp" <?php if ($pconfig['dst'] == "l2tp") { echo "selected"; } ?>>L2TP clients</option>
614
                                                                <?php endif; ?>
615

    
616
<?php 							foreach ($ifdisp as $if => $ifdesc): ?>
617
								<?php if(have_ruleint_access($if)): ?>
618
									<option value="<?=$if;?>" <?php if ($pconfig['dst'] == $if) { echo "selected"; } ?>><?=htmlspecialchars($ifdesc);?> subnet</option>
619
									<option value="<?=$if;?>ip"<?php if ($pconfig['dst'] == $if . "ip") { echo "selected"; } ?>>
620
										<?=$ifdesc;?> address
621
									</option>
622
								<?php endif; ?>
623
<?php 							endforeach; ?>
624

    
625
<?php							if (is_array($config['virtualip']['vip'])):
626
									foreach ($config['virtualip']['vip'] as $sn):
627
										if ($sn['mode'] == "proxyarp" && $sn['type'] == "network"):
628
											$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
629
											$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
630
											$len = $end - $start;
631
											for ($i = 0; $i <= $len; $i++):
632
												$snip = long2ip32($start+$i);
633
?>
634
												<option value="<?=$snip;?>" <?php if ($snip == $pconfig['dst']) echo "selected"; ?>><?=htmlspecialchars("{$snip} ({$sn['descr']})");?></option>
635
<?php										endfor;
636
										else:
637
?>
638
											<option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['dst']) echo "selected"; ?>><?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?></option>
639
<?php									endif;
640
									endforeach;
641
								endif;
642
?>
643
							</select>
644
						</td>
645
					</tr>
646
					<tr>
647
						<td>Address:&nbsp;&nbsp;</td>
648
						<td>
649
							<input name="dst" type="text" class="formfldalias" id="dst" size="20" value="<?php if (!is_specialnet($pconfig['dst'])) echo htmlspecialchars($pconfig['dst']);?>">
650
							/
651
							<select name="dstmask" class="formselect" id="dstmask">
652
<?php
653
							for ($i = 31; $i > 0; $i--): ?>
654
								<option value="<?=$i;?>" <?php if ($i == $pconfig['dstmask']) echo "selected"; ?>><?=$i;?></option>
655
<?php						endfor; ?>
656
							</select>
657
						</td>
658
					</tr>
659
				</table>
660
			</td>
661
		</tr>
662
		<tr id="dprtr" name="dprtr">
663
			<td width="22%" valign="top" class="vncellreq">Destination port range </td>
664
			<td width="78%" class="vtable">
665
				<table border="0" cellspacing="0" cellpadding="0">
666
					<tr>
667
						<td>from:&nbsp;&nbsp;</td>
668
						<td>
669
							<select name="dstbeginport" class="formselect" onchange="dst_rep_change();ext_change()">
670
								<option value="">(other)</option>
671
<?php 							$bfound = 0;
672
								foreach ($wkports as $wkport => $wkportdesc): ?>
673
									<option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstbeginport']) { echo "selected"; $bfound = 1; }?>><?=htmlspecialchars($wkportdesc);?></option>
674
<?php 							endforeach; ?>
675
							</select>
676
							<input autocomplete='off' class="formfldalias" name="dstbeginport_cust" id="dstbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstbeginport']) echo $pconfig['dstbeginport']; ?>">
677
						</td>
678
					</tr>
679
					<tr>
680
						<td>to:</td>
681
						<td>
682
							<select name="dstendport" class="formselect" onchange="ext_change()">
683
								<option value="">(other)</option>
684
<?php							$bfound = 0;
685
								foreach ($wkports as $wkport => $wkportdesc): ?>
686
									<option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstendport']) { echo "selected"; $bfound = 1; } ?>><?=htmlspecialchars($wkportdesc);?></option>
687
<?php 							endforeach; ?>
688
							</select>
689
							<input autocomplete='off' class="formfldalias" name="dstendport_cust" id="dstendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstendport']) echo $pconfig['dstendport']; ?>">
690
						</td>
691
					</tr>
692
				</table>
693
				<br />
694
				<span class="vexpl">
695
					Specify the port or port range for the destination of the packet for this mapping.
696
					<br />
697
					Hint: you can leave the <em>'to'</em> field empty if you only want to map a single port
698
				</span>
699
			</td>
700
		</tr>
701
                <tr>
702
                  <td width="22%" valign="top" class="vncellreq">Redirect target IP</td>
703
                  <td width="78%" class="vtable">
704
                    <input autocomplete='off' name="localip" type="text" class="formfldalias" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>">
705
                    <br> <span class="vexpl">Enter the internal IP address of
706
                    the server on which you want to map the ports.<br>
707
                    e.g. <em>192.168.1.12</em></span></td>
708
                </tr>
709
                <tr name="lprtr" id="lprtr">
710
                  <td width="22%" valign="top" class="vncellreq">Redirect target port</td>
711
                  <td width="78%" class="vtable">
712
                    <select name="localbeginport" class="formselect" onChange="ext_change();check_for_aliases();">
713
                      <option value="">(other)</option>
714
                      <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
715
                      <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['localbeginport']) {
716
							echo "selected";
717
							$bfound = 1;
718
						}?>>
719
					  <?=htmlspecialchars($wkportdesc);?>
720
					  </option>
721
                      <?php endforeach; ?>
722
                    </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']; ?>">
723
                    <br>
724
                    <span class="vexpl">Specify the port on the machine with the
725
                    IP address entered above. In case of a port range, specify
726
                    the beginning port of the range (the end port will be calculated
727
                    automatically).<br>
728
                    Hint: this is usually identical to the 'from' port above</span></td>
729
                </tr>
730
                <tr>
731
                  <td width="22%" valign="top" class="vncell">Description</td>
732
                  <td width="78%" class="vtable">
733
                    <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
734
                    <br> <span class="vexpl">You may enter a description here
735
                    for your reference (not parsed).</span></td>
736
                </tr>
737
				<tr>
738
					<td width="22%" valign="top" class="vncell">No XMLRPC Sync</td>
739
					<td width="78%" class="vtable">
740
						<input type="checkbox" value="yes" name="nosync"<?php if($pconfig['nosync']) echo " CHECKED"; ?>><br>
741
						HINT: This prevents the rule from automatically syncing to other CARP members.
742
					</td>
743
				</tr>
744
				<?php if (isset($id) && $a_nat[$id] && !isset($_GET['dup'])): ?>
745
				<tr>
746
					<td width="22%" valign="top" class="vncell">Filter rule association</td>
747
					<td width="78%" class="vtable">
748
						<select name="associated-rule-id">
749
							<option value="">None</option>
750
							<option value="pass" <?php if($pconfig['associated-rule-id'] == "pass") echo " SELECTED"; ?>>Pass</option>
751
							<?php
752
							$linkedrule = "";
753
							if (is_array($config['filter']['rule'])) {
754
								$filter_id = 0;
755
							      foreach ($config['filter']['rule'] as $filter_rule) {
756
								if (isset($filter_rule['associated-rule-id'])) {
757
									echo "<option value=\"{$filter_rule['associated-rule-id']}\"";
758
									if ($filter_rule['associated-rule-id']==$pconfig['associated-rule-id']) {
759
										echo " SELECTED";
760
										$linkedrule = "<br /><a href=\"firewall_rules_edit.php?id={$filter_id}\">View the filter rule</a><br/>";
761
									}
762
									echo ">". htmlspecialchars('Rule ' . $filter_rule['descr']) . "</option>\n";
763

    
764
								}
765
								if ($filter_rule['interface'] == $pconfig['interface'])
766
									$filter_id++;
767
							      }
768
							}
769
							if (isset($pconfig['associated-rule-id']))
770
								echo "<option value=\"new\">Create new associated filter rule</option>\n";
771
						echo "</select>\n";
772
						echo $linkedrule;
773
						?>
774
					</td>
775
				</tr>
776
				<?php endif; ?>
777
                <?php if ((!(isset($id) && $a_nat[$id])) || (isset($_GET['dup']))): ?>
778
                <tr>
779
                  <td width="22%" valign="top" class="vncell">Filter rule association</td>
780
                  <td width="78%" class="vtable">
781
                    <select name="filter-rule-association" id="filter-rule-association">
782
						<option value="">None</option>
783
						<option value="add-associated" selected="selected">Add associated filter rule</option>
784
						<option value="add-unassociated">Add unassociated filter rule</option>
785
						<option value="pass">Pass</option>
786
					</select>
787
				  </td>
788
                </tr><?php endif; ?>
789
				<tr>
790
                  <td width="22%" valign="top">&nbsp;</td>
791
                  <td width="78%">&nbsp;</td>
792
				</tr>
793
                <tr>
794
                  <td width="22%" valign="top">&nbsp;</td>
795
                  <td width="78%">
796
                    <input name="Submit" type="submit" class="formbtn" value="Save"> <input type="button" class="formbtn" value="Cancel" onclick="history.back()">
797
                    <?php if (isset($id) && $a_nat[$id]): ?>
798
                    <input name="id" type="hidden" value="<?=$id;?>">
799
                    <?php endif; ?>
800
                  </td>
801
                </tr>
802
              </table>
803
</form>
804
<script language="JavaScript">
805
<!--
806
	ext_change();
807
	dst_change(document.iform.interface.value,'<?=$pconfig['interface']?>','<?=$pconfig['dst']?>');
808
	var iface_old = document.iform.interface.value;
809
	typesel_change();
810
	proto_change();
811
	<?php if ($pconfig['srcnot'] || $pconfig['src'] != "any" || $pconfig['srcbeginport'] != "any" || $pconfig['srcendport'] != "any"): ?>
812
	show_source();
813
	<?php endif; ?>
814
//-->
815
</script>
816
<?php
817
$isfirst = 0;
818
$aliases = "";
819
$addrisfirst = 0;
820
$aliasesaddr = "";
821
if($config['aliases']['alias'] <> "")
822
	foreach($config['aliases']['alias'] as $alias_name) {
823
		switch ($alias_name['type']) {
824
                        case "port":
825
                                if($isfirst == 1) $portaliases .= ",";
826
                                $portaliases .= "'" . $alias_name['name'] . "'";
827
                                $isfirst = 1;
828
                                break;
829
                        case "host":
830
                        case "network":
831
                        case "openvpn":
832
			case "urltable":
833
                                if($addrisfirst == 1) $aliasesaddr .= ",";
834
                                $aliasesaddr .= "'" . $alias_name['name'] . "'";
835
                                $addrisfirst = 1;
836
                                break;
837
                        default:
838
                                break;
839
		}
840
	}
841
?>
842
<script language="JavaScript">
843
<!--
844
	var addressarray=new Array(<?php echo $aliasesaddr; ?>);
845
	var customarray=new Array(<?php echo $portaliases; ?>);
846

    
847
	var oTextbox1 = new AutoSuggestControl(document.getElementById("localip"), new StateSuggestions(addressarray));
848
	var oTextbox2 = new AutoSuggestControl(document.getElementById("src"), new StateSuggestions(addressarray));
849
	var oTextbox3 = new AutoSuggestControl(document.getElementById("dst"), new StateSuggestions(addressarray));
850
	var oTextbox4 = new AutoSuggestControl(document.getElementById("dstbeginport_cust"), new StateSuggestions(customarray));
851
	var oTextbox5 = new AutoSuggestControl(document.getElementById("dstendport_cust"), new StateSuggestions(customarray));
852
	var oTextbox6 = new AutoSuggestControl(document.getElementById("srcbeginport_cust"), new StateSuggestions(customarray));
853
	var oTextbox7 = new AutoSuggestControl(document.getElementById("srcendport_cust"), new StateSuggestions(customarray));
854
	var oTextbox8 = new AutoSuggestControl(document.getElementById("localbeginport_cust"), new StateSuggestions(customarray));
855
//-->
856
</script>
857
<?php include("fend.inc"); ?>
858
</body>
859
</html>
(53-53/221)