Project

General

Profile

Download (12.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	firewall_nat.php
5
	Copyright© 2015 Rubicon Communications, LLC (Netgate)
6
	This file is a part of pfSense (C)
7

    
8
	Copyright (C) 2004 Scott Ullrich
9
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
10
	All rights reserved.
11

    
12
	originally part of m0n0wall (http://m0n0.ch/wall)
13
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
	All rights reserved.
15

    
16
	Redistribution and use in source and binary forms, with or without
17
	modification, are permitted provided that the following conditions are met:
18

    
19
	1. Redistributions of source code must retain the above copyright notice,
20
	   this list of conditions and the following disclaimer.
21

    
22
	2. Redistributions in binary form must reproduce the above copyright
23
	   notice, this list of conditions and the following disclaimer in the
24
	   documentation and/or other materials provided with the distribution.
25

    
26
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
	POSSIBILITY OF SUCH DAMAGE.
36
*/
37
/*
38
	pfSense_MODULE: nat
39
*/
40

    
41
##|+PRIV
42
##|*IDENT=page-firewall-nat-portforward
43
##|*NAME=Firewall: NAT: Port Forward page
44
##|*DESCR=Allow access to the 'Firewall: NAT: Port Forward' page.
45
##|*MATCH=firewall_nat.php*
46
##|-PRIV
47

    
48
require("guiconfig.inc");
49
require_once("functions.inc");
50
require_once("filter.inc");
51
require_once("shaper.inc");
52
require_once("itemid.inc");
53

    
54
if (!is_array($config['nat']['rule']))
55
	$config['nat']['rule'] = array();
56

    
57
$a_nat = &$config['nat']['rule'];
58

    
59
/* update rule order, POST[rule] is an array of ordered IDs */
60
if (is_array($_POST['rule']) && !empty($_POST['rule'])) {
61
	$a_nat_new = array();
62

    
63
	// if a rule is not in POST[rule], it has been deleted by the user
64
	foreach ($_POST['rule'] as $id)
65
		$a_nat_new[] = $a_nat[$id];
66

    
67
	$a_nat = $a_nat_new;
68

    
69
	if (write_config())
70
		mark_subsystem_dirty('filter');
71

    
72
	header("Location: firewall_nat.php");
73
	exit;
74
}
75

    
76
/* if a custom message has been passed along, lets process it */
77
if ($_GET['savemsg'])
78
	$savemsg = $_GET['savemsg'];
79

    
80
if ($_POST) {
81

    
82
	$pconfig = $_POST;
83

    
84
	if ($_POST['apply']) {
85

    
86
		$retval = 0;
87

    
88
		$retval |= filter_configure();
89
		$savemsg = get_std_save_message($retval);
90

    
91
		pfSense_handle_custom_code("/usr/local/pkg/firewall_nat/apply");
92

    
93
		if ($retval == 0) {
94
			clear_subsystem_dirty('natconf');
95
			clear_subsystem_dirty('filter');
96
		}
97

    
98
	}
99
}
100

    
101
if ($_GET['act'] == "del") {
102
	if ($a_nat[$_GET['id']]) {
103

    
104
		if (isset($a_nat[$_GET['id']]['associated-rule-id'])) {
105
			delete_id($a_nat[$_GET['id']]['associated-rule-id'], $config['filter']['rule']);
106
			$want_dirty_filter = true;
107
		}
108
		unset($a_nat[$_GET['id']]);
109

    
110
		if (write_config()) {
111
			mark_subsystem_dirty('natconf');
112
			if ($want_dirty_filter)
113
				mark_subsystem_dirty('filter');
114
		}
115

    
116
		header("Location: firewall_nat.php");
117
		exit;
118
	}
119
}
120

    
121
if (isset($_POST['del_x'])) {
122
	/* delete selected rules */
123
	if (is_array($_POST['rule']) && count($_POST['rule'])) {
124
		foreach ($_POST['rule'] as $rulei) {
125
		$target = $rule['target'];
126
			// Check for filter rule associations
127
			if (isset($a_nat[$rulei]['associated-rule-id'])){
128
				delete_id($a_nat[$rulei]['associated-rule-id'], $config['filter']['rule']);
129

    
130
				mark_subsystem_dirty('filter');
131
			}
132
			unset($a_nat[$rulei]);
133
		}
134

    
135
		if (write_config())
136
			mark_subsystem_dirty('natconf');
137

    
138
		header("Location: firewall_nat.php");
139
		exit;
140
	}
141

    
142
} else {
143
	/* yuck - IE won't send value attributes for image buttons, while Mozilla does - so we use .x/.y to find move button clicks instead... */
144
	unset($movebtn);
145
	foreach ($_POST as $pn => $pd) {
146
		if (preg_match("/move_(\d+)_x/", $pn, $matches)) {
147
				$movebtn = $matches[1];
148
				break;
149
		}
150
	}
151
	/* move selected rules before this rule */
152
	if (isset($movebtn) && is_array($_POST['rule']) && count($_POST['rule'])) {
153
		$a_nat_new = array();
154

    
155
		/* copy all rules < $movebtn and not selected */
156
		for ($i = 0; $i < $movebtn; $i++) {
157
				if (!in_array($i, $_POST['rule']))
158
						$a_nat_new[] = $a_nat[$i];
159
		}
160

    
161
		/* copy all selected rules */
162
		for ($i = 0; $i < count($a_nat); $i++) {
163
				if ($i == $movebtn)
164
						continue;
165
				if (in_array($i, $_POST['rule']))
166
						$a_nat_new[] = $a_nat[$i];
167
		}
168

    
169
		/* copy $movebtn rule */
170
		if ($movebtn < count($a_nat))
171
				$a_nat_new[] = $a_nat[$movebtn];
172

    
173
		/* copy all rules > $movebtn and not selected */
174
		for ($i = $movebtn+1; $i < count($a_nat); $i++) {
175
				if (!in_array($i, $_POST['rule']))
176
						$a_nat_new[] = $a_nat[$i];
177
		}
178

    
179
	$a_nat = $a_nat_new;
180

    
181
	if (write_config())
182
		mark_subsystem_dirty('natconf');
183
		header("Location: firewall_nat.php");
184
		exit;
185
	}
186
}
187

    
188
?>
189
<script>
190
// Check the checkbox, and change the background color when clicking on a row
191
function fr_toggle(id, prefix) {
192

    
193
	if (!prefix)
194
		prefix = 'fr';
195

    
196
	var checkbox = document.getElementById(prefix + 'c' + id);
197

    
198
	checkbox.checked = !checkbox.checked;
199
	fr_bgcolor(id, prefix);
200
}
201

    
202
function fr_bgcolor(id, prefix) {
203
	if (!prefix)
204
		prefix = 'fr';
205

    
206
	var row = document.getElementById(prefix + id);
207
	var checkbox = document.getElementById(prefix + 'c' + id);
208
	var cells = row.getElementsByTagName('td');
209
	var cellcnt = cells.length;
210

    
211
	for (i = 0; i < cellcnt; i++)
212
		cells[i].style.backgroundColor = checkbox.checked ? "#B9DEF0" : "#FFFFFF";
213
}
214
</script>
215
<?php
216

    
217
$closehead = false;
218
$pgtitle = array(gettext("Firewall"),gettext("NAT"),gettext("Port Forward"));
219
include("head.inc");
220

    
221
if ($savemsg)
222
	print_info_box($savemsg, 'success');
223

    
224
if (is_subsystem_dirty('natconf'))
225
	print_info_box_np(gettext('The NAT configuration has been changed.') . '<br />' .
226
					  gettext('You must apply the changes in order for them to take effect.') . '<br />');
227

    
228
$tab_array = array();
229
$tab_array[] = array(gettext("Port Forward"), true, "firewall_nat.php");
230
$tab_array[] = array(gettext("1:1"), false, "firewall_nat_1to1.php");
231
$tab_array[] = array(gettext("Outbound"), false, "firewall_nat_out.php");
232
$tab_array[] = array(gettext("NPt"), false, "firewall_nat_npt.php");
233
display_top_tabs($tab_array);
234
?>
235

    
236
<form action="firewall_nat.php" method="post" name="iform">
237
	<div class="panel panel-default">
238
		<div class="panel-heading"><?=gettext('Rules')?></div>
239
		<div class="panel-body table-responsive">
240
			<table class="table table-striped table-hover table-condensed">
241
				<thead>
242
					<tr>
243
						<th><!-- Checkbox --></th>
244
						<th><!-- Rule type --></th>
245
						<th><?=gettext("If")?></th>
246
						<th><?=gettext("Proto")?></th>
247
						<th><?=gettext("Src. addr")?></th>
248
						<th><?=gettext("Src. ports")?></th>
249
						<th><?=gettext("Dest. addr")?></th>
250
						<th><?=gettext("Dest. ports")?></th>
251
						<th><?=gettext("NAT IP")?></th>
252
						<th><?=gettext("NAT Ports")?></th>
253
						<th><?=gettext("Description")?></th>
254
						<th><?=gettext("Actions")?></th>
255
					</tr>
256
				</thead>
257
				<tbody class='user-entries'>
258
<?php
259

    
260
$nnats = $i = 0;
261

    
262
foreach ($a_nat as $natent):
263

    
264
	$alias = rule_columns_with_alias(
265
		$natent['source']['address'],
266
		pprint_port($natent['source']['port']),
267
		$natent['destination']['address'],
268
		pprint_port($natent['destination']['port'])
269
	);
270

    
271
	/* if user does not have access to edit an interface skip on to the next record */
272
	if(!have_natpfruleint_access($natent['interface']))
273
		continue;
274
?>
275
					<tr id="fr<?=$nnats?>">
276
						<td>
277
							<input type="hidden" name="rule[]" value="<?=$i?>" />
278
							<input type="checkbox" id="frc<?=$nnats?>" name="rule[]" value="<?=$i?>" onClick="fr_bgcolor('<?=$nnats?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;" /></td>
279
						<td>
280
<?php
281
	if($natent['associated-rule-id'] == "pass"):
282
?>
283
							<img src="/bootstrap/glyphicons/glyphicons-halflings.png" class="icon-play" title="<?=gettext("All traffic matching this NAT entry is passed"); ?>" border="0" alt="pass" />
284
<?php
285
	elseif (!empty($natent['associated-rule-id'])):
286
?>
287
							<img src="/bootstrap/glyphicons/glyphicons-halflings.png" class="icon-random" title="<?=gettext("Firewall rule ID"); ?><?=htmlspecialchars($nnatid); ?><?=gettext("is managed with this rule"); ?>" alt="change" />
288
<?php
289
	endif;
290
?>
291
						</td>
292
						<td onClick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
293
							<?=$textss?>
294
<?php
295
	if (!$natent['interface'])
296
		echo htmlspecialchars(convert_friendly_interface_to_friendly_descr("wan"));
297
	else
298
		echo htmlspecialchars(convert_friendly_interface_to_friendly_descr($natent['interface']));
299
?>
300
							<?=$textse?>
301
						</td>
302

    
303
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
304
							<?=$textss?><?=strtoupper($natent['protocol'])?><?=$textse?>
305
						</td>
306

    
307
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>">
308

    
309

    
310
<?php
311
	if (isset($alias['src'])):
312
?>
313
							<a href="/firewall_aliases_edit.php?id=<?=$alias['src']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['src'])?>" data-html="true">
314
<?php
315
	endif;
316
?>
317
							<?=htmlspecialchars(pprint_address($natent['source']))?>
318
<?php
319
	if (isset($alias['src'])):
320
?>
321
							<i class='icon icon-pencil'></i></a>
322
<?php
323
	endif;
324
?>
325
						</td>
326
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
327
<?php
328
	if (isset($alias['srcport'])):
329
?>
330
							<a href="/firewall_aliases_edit.php?id=<?=$alias['srcport']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['srcport'])?>" data-html="true">
331
<?php
332
	endif;
333
?>
334
							<?=htmlspecialchars(pprint_port($natent['source']['port']))?>
335
<?php
336
	if (isset($alias['srcport'])):
337
?>
338
							<i class='icon icon-pencil'></i></a>
339
<?php
340
	endif;
341
?>
342
						</td>
343

    
344
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
345
<?php
346
	if (isset($alias['dst'])):
347
?>
348
							<a href="/firewall_aliases_edit.php?id=<?=$alias['dst']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['dst'])?>" data-html="true">
349
<?php
350
	endif;
351
?>
352
							<?=htmlspecialchars(pprint_address($natent['destination']))?>
353
<?php
354
	if (isset($alias['dst'])):
355
?>
356
							<i class='icon icon-pencil'></i></a>
357
<?php
358
	endif;
359
?>
360
						</td>
361
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
362
<?php
363
	if (isset($alias['dstport'])):
364
?>
365
							<a href="/firewall_aliases_edit.php?id=<?=$alias['dstport']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['dstport'])?>" data-html="true">
366
<?php
367
	endif;
368
?>
369
							<?=htmlspecialchars(pprint_port($natent['destination']['port']))?>
370
<?php
371
	if (isset($alias['dstport'])):
372
?>
373
							<i class='icon icon-pencil'></i></a>
374
<?php
375
	endif;
376
?>
377
						</td>
378

    
379
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
380
							<?=htmlspecialchars($natent['target'])?>
381
						</td>
382
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>" >
383
<?php
384
	$localport = $natent['local-port'];
385

    
386
	list($dstbeginport, $dstendport) = explode("-", $natent['destination']['port']);
387

    
388
	if ($dstendport) {
389
		$localendport = $natent['local-port'] + $dstendport - $dstbeginport;
390
		$localport	 .= '-' . $localendport;
391
	}
392
?>
393
							<?=htmlspecialchars(pprint_port($localport))?>
394
						</td>
395

    
396
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>">
397
							<?=htmlspecialchars($natent['descr'])?>
398
						</td>
399
						<td onclick="fr_toggle(<?=$nnats?>)" id="frd<?=$nnats?>">
400
							<a class="btn btn-xs btn-info"	title="<?=gettext("Edit rule"); ?>" href="firewall_nat_edit.php?id=<?=$i?>"><?=gettext("Edit"); ?></a>
401
							<a class="btn btn-xs btn-danger"  title="<?=gettext("Delete rule")?>" href="firewall_nat.php?act=del&amp;id=<?=$i?>"><?=gettext("Del")?></a>
402
							<a class="btn btn-xs btn-success"	  title="<?=gettext("Add a new NAT based on this one")?>" href="firewall_nat_edit.php?dup=<?=$i?>"><?=gettext("Clone")?></a>
403
						</td>
404
					</tr>
405
<?php
406
	$i++;
407
	$nnats++;
408
endforeach;
409
?>
410
				</tbody>
411
			</table>
412
		</div>
413
	</div>
414

    
415
	<div class="pull-right">
416
		<a href="firewall_nat_edit.php?after=-1" class="btn btn-sm btn-success" title="<?=gettext('Add new rule')?>"><?=gettext('Add new rule')?></a>
417
		<input type="submit" id="order-store" class="btn btn-primary btn-sm" value="store changes" disabled="disabled" />
418
	</div>
419
</form>
420

    
421
<script>
422
events.push(function() {
423
	// Make rules draggable/sortable
424
	$('table tbody.user-entries').sortable({
425
		cursor: 'grabbing',
426
		update: function(event, ui) {
427
			$('#order-store').removeAttr('disabled');
428
		}
429
	});
430
});
431
</script>
432
<?php
433

    
434
if(count($a_nat) > 0) {
435
?>
436
<!-- Legend -->
437
<div>
438
	<dl class="dl-horizontal responsive">
439
		<dt><?=gettext('Legend')?></dt>					<dd></dd>
440
		<dt><i class="icon icon-play"></i></dt>			<dd><?=gettext('Pass')?></dd>
441
		<dt><i class="icon icon-random"></i></dt>		<dd><?=gettext('Linked rule')?></dd>
442
	</dl>
443
</div>
444

    
445
<?php
446
}
447

    
448
include("foot.inc");
(52-52/241)