From 624684a2937cf05ce4a14c1180759fcba3b4dfe8 Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Sun, 15 Jan 2023 20:50:12 -0700 Subject: [PATCH] [pfsense_nat_port_forward] Handle non-TCP/UDP protocols Fixes #28 --- plugins/module_utils/nat_port_forward.py | 19 ++++++++++++----- .../modules/test_pfsense_nat_port_forward.py | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/plugins/module_utils/nat_port_forward.py b/plugins/module_utils/nat_port_forward.py index 365966bb..9e5772d7 100644 --- a/plugins/module_utils/nat_port_forward.py +++ b/plugins/module_utils/nat_port_forward.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Copyright: (c) 2019, Frederic Bor +# Copyright: (c) 2023, Orion Poplwski # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function @@ -120,10 +121,16 @@ def _parse_target_address(self, obj): else: self.module.fail_json(msg='"%s" is not a valid redirect target IP address or host alias.' % (param)) - if ports is not None and self.pfsense.is_port_or_alias(ports): - obj['local-port'] = ports - else: - self.module.fail_json(msg='"{0}" is not a valid redirect target port. It must be a port alias or integer between 1 and 65535.'.format(ports)) + if ports is None and self.params['protocol'] in ["tcp", "udp", "tcp/udp"]: + self.module.fail_json(msg='Must specify a target port with protocol "{0}".'.format(self.params['protocol'])) + + if ports is not None: + if self.params['protocol'] not in ["tcp", "udp", "tcp/udp"]: + self.module.fail_json(msg='Cannot specify a target port with protocol "{0}".'.format(self.params['protocol'])) + elif self.pfsense.is_port_or_alias(ports): + obj['local-port'] = ports + else: + self.module.fail_json(msg='"{0}" is not a valid redirect target port. It must be a port alias or integer between 1 and 65535.'.format(ports)) def _validate_params(self): """ do some extra checks on input parameters """ @@ -436,7 +443,9 @@ def _obj_to_log_fields(self, rule): res = {} res['source'] = self._obj_address_to_log_field(rule, 'source') res['destination'] = self._obj_address_to_log_field(rule, 'destination') - res['target'] = rule['target'] + ':' + rule['local-port'] + res['target'] = rule['target'] + if 'local-port' in rule: + res['target'] += ':' + rule['local-port'] res['interface'] = self.pfsense.get_interface_display_name(rule['interface']) return res diff --git a/tests/unit/plugins/modules/test_pfsense_nat_port_forward.py b/tests/unit/plugins/modules/test_pfsense_nat_port_forward.py index 0aafd11e..c52c970d 100644 --- a/tests/unit/plugins/modules/test_pfsense_nat_port_forward.py +++ b/tests/unit/plugins/modules/test_pfsense_nat_port_forward.py @@ -161,6 +161,27 @@ def test_nat_port_forward_create_before(self): ) self.do_module_test(obj, command=command, target_idx=1) + def test_nat_port_forward_create_icmp(self): + """ test """ + obj = dict(descr='test_pf', interface='wan', protocol='icmp', source='any', destination='1.2.3.4', target='2.3.4.5', associated_rule='associated') + command = [ + "create rule 'NAT test_pf' on 'wan', source='any', destination='2.3.4.5', protocol='icmp'", + "create nat_port_forward 'test_pf', interface='wan', protocol='icmp', source='any', destination='1.2.3.4', target='2.3.4.5'" + ] + self.do_module_test(obj, command=command, target_idx=3) + + def test_nat_port_forward_create_tcp_fail_no_port(self): + """ test """ + obj = dict(descr='test_pf', interface='wan', source='any', destination='1.2.3.4', target='2.3.4.5', associated_rule='associated') + msg = 'Must specify a target port with protocol "tcp".' + self.do_module_test(obj, failed=True, msg=msg) + + def test_nat_port_forward_create_icmp_fail_port(self): + """ test """ + obj = dict(descr='test_pf', interface='wan', protocol='icmp', source='any', destination='1.2.3.4', target='2.3.4.5:443', associated_rule='associated') + msg = 'Cannot specify a target port with protocol "icmp".' + self.do_module_test(obj, failed=True, msg=msg) + def test_nat_port_forward_update_noop(self): """ test """ obj = dict(descr='one', interface='wan', source='any', destination='IP:wan:22022', target='10.255.1.20:22', associated_rule='none')