diff --git a/fake_switches/cisco/command_processor/config_interface.py b/fake_switches/cisco/command_processor/config_interface.py index 29195051..99af3a75 100644 --- a/fake_switches/cisco/command_processor/config_interface.py +++ b/fake_switches/cisco/command_processor/config_interface.py @@ -18,6 +18,8 @@ from fake_switches.command_processing.base_command_processor import BaseCommandProcessor from fake_switches.switch_configuration import VlanPort +from fake_switches.utils.ip_validator import InvalidIpError, IncompleteIpError, valid_ip_v4 + class ConfigInterfaceCommandProcessor(BaseCommandProcessor): def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args): @@ -139,9 +141,19 @@ def do_ip(self, *args): self.write_line("% Invalid input detected at '^' marker.") self.write_line("") else: - ip_address = IPAddress(args[1]) - if ip_address not in self.port.ip_helpers: - self.port.ip_helpers.append(ip_address) + try: + ip_address = _parse_ip(args[1], 4) + if ip_address is None: + raise InvalidIpError + if ip_address not in self.port.ip_helpers: + self.port.ip_helpers.append(ip_address) + except InvalidIpError: + self.write_line(" ^") + self.write_line("% Invalid input detected at '^' marker.") + self.write_line("") + except IncompleteIpError: + self.write_line("% Incomplete command.") + self.write_line("") def do_no_ip(self, *args): if "address".startswith(args[0]): @@ -333,7 +345,11 @@ def parse_vlan_list(param): return vlans -def _parse_ip(ip): +def _parse_ip(ip, strict_format=None): + if strict_format == 4 and not valid_ip_v4(ip): + return None + elif strict_format and strict_format != 4: + raise NotImplementedError("Ip format {} validation not supported.".format(strict_format)) try: return IPAddress(ip) except: diff --git a/fake_switches/utils/__init__.py b/fake_switches/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fake_switches/utils/ip_validator.py b/fake_switches/utils/ip_validator.py new file mode 100644 index 00000000..f42cef7d --- /dev/null +++ b/fake_switches/utils/ip_validator.py @@ -0,0 +1,16 @@ +def valid_ip_v4(address): + parts = address.split(".") + for item in parts: + if not item.isdigit() or not 0 <= int(item) <= 255: + raise InvalidIpError + if len(parts) != 4: + raise IncompleteIpError + return True + + +class InvalidIpError(Exception): + pass + + +class IncompleteIpError(Exception): + pass diff --git a/tests/cisco/test_cisco_switch_protocol.py b/tests/cisco/test_cisco_switch_protocol.py index d7b859a2..53b87f24 100644 --- a/tests/cisco/test_cisco_switch_protocol.py +++ b/tests/cisco/test_cisco_switch_protocol.py @@ -1240,8 +1240,23 @@ def test_ip_helper(self, t): t.write("ip helper-address") t.readln("% Incomplete command.") t.readln("") + + t.read("my_switch(config-if)#") + t.write("ip helper-address 1.1.1") + t.readln("% Incomplete command.") + t.readln("") t.read("my_switch(config-if)#") + t.write("ip helper-address 1.a.1") + t.readln(" ^") + t.readln("% Invalid input detected at '^' marker.") # not incomplete + t.readln("") + t.read("my_switch(config-if)#") + t.write("ip helper-address invalid.ip") + t.readln(" ^") + t.readln("% Invalid input detected at '^' marker.") + t.readln("") + t.read("my_switch(config-if)#") t.write("ip helper-address 10.10.0.1 EXTRA INFO") t.readln(" ^") t.readln("% Invalid input detected at '^' marker.")