def test_no_verification_sequence_nested_messages( sequence_message_package: Package, message_sequence_value: MessageValue) -> None: sequence_message_one = sequence_message_package.new_message( "Sequence_Element") sequence_message_one.set("Byte", 5) sequence_message_two = sequence_message_package.new_message( "Sequence_Element") sequence_message_two.set("Byte", 6) sequence: List[TypeValue] = [sequence_message_one, sequence_message_two] message_sequence_value.set("Length", 2) message_sequence_value.set("Sequence_Field", sequence) assert message_sequence_value.valid_message pyrflx_ = PyRFLX.from_specs( [SPEC_DIR / "sequence_message.rflx"], skip_model_verification=True, skip_message_verification=True, ) sequence_message_package_unv = pyrflx_.package("Sequence_Message") sequence_message_unv = sequence_message_package_unv.new_message( "Message_Sequence") sequence_element_one_unv = sequence_message_package_unv.new_message( "Sequence_Element") sequence_element_one_unv.set("Byte", 5) sequence_element_two_unv = sequence_message_package_unv.new_message( "Sequence_Element") sequence_element_two_unv.set("Byte", 6) sequence_unv: List[TypeValue] = [ sequence_element_one_unv, sequence_element_two_unv ] sequence_message_unv.set("Length", 2) sequence_message_unv.set("Sequence_Field", sequence_unv) assert sequence_message_unv.valid_message assert sequence_message_unv.bytestring == message_sequence_value.bytestring
def __init__(self, specdir: Path) -> None: print("Loading...") start = perf_counter() self.__pyrflx = PyRFLX.from_specs( [str(specdir / "ipv4.rflx"), str(specdir / "icmp.rflx")], skip_model_verification=True, skip_message_verification=True, ) self.__ipv4 = self.__pyrflx.package("IPv4") self.__icmp = self.__pyrflx.package("ICMP") print(f"Loaded in {perf_counter() - start} seconds")
def test_validate_message_parameterized_message() -> None: validator = Validator([], skip_model_verification=True) message = (PyRFLX.from_specs(["tests/data/specs/parameterized.rflx"], skip_model_verification=True).package( "Parameterized").new_message("Message")) validation_result = validator._validate_message( # pylint: disable = protected-access Path(TEST_DIR / "parameterized/message/valid/parameterized_message.raw"), valid_original_message=True, message_value=message, ) assert validation_result.validation_success
def test_validate_message_original_and_parsed_not_equal() -> None: validator = Validator([], skip_model_verification=True) ethernet_too_short_value = (PyRFLX.from_specs( [SPEC_DIR / "ethernet.rflx"], skip_model_verification=True).package("Ethernet").new_message("Frame")) validation_result = validator._validate_message( # pylint: disable = protected-access Path(TEST_DIR / "ethernet/frame/invalid/ethernet_invalid_too_long.raw"), valid_original_message=True, message_value=ethernet_too_short_value, ) assert (validation_result.parser_error == "message parsed by PyRFLX is shorter than the original message")
def test_parameterized_message_excess_parameter() -> None: validator = Validator([], skip_model_verification=True) message = (PyRFLX.from_specs(["tests/data/specs/parameterized.rflx"], skip_model_verification=True).package( "Parameterized").new_message("Message")) with pytest.raises( ValidationError, match= (r"^" f"{TEST_DIR}/parameterized/message/invalid/parameterized_message_excess_parameter.raw:" r" pyrflx: error: unexpected parameter values: Excess" r"$"), ): validator._validate_message( # pylint: disable = protected-access Path( TEST_DIR / "parameterized/message/invalid/parameterized_message_excess_parameter.raw" ), valid_original_message=True, message_value=message, )
def test_no_verification_ethernet(ethernet_frame_value: MessageValue) -> None: payload = (b"\x45\x00\x00\x2e\x00\x01\x00\x00\x40\x11\x7c\xbc" b"\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x35\x00\x35" b"\x00\x1a\x01\x4e\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") ethernet_frame_value.set("Destination", int("FFFFFFFFFFFF", 16)) ethernet_frame_value.set("Source", int("0", 16)) ethernet_frame_value.set("Type_Length_TPID", int("0800", 16)) ethernet_frame_value.set("Type_Length", int("0800", 16)) ethernet_frame_value.set("Payload", payload) assert ethernet_frame_value.valid_message pyrflx_ = PyRFLX.from_specs( [SPEC_DIR / "ethernet.rflx"], skip_model_verification=True, skip_message_verification=True, ) frame_unv = pyrflx_.package("Ethernet").new_message("Frame") frame_unv.set("Destination", int("FFFFFFFFFFFF", 16)) frame_unv.set("Source", int("0", 16)) frame_unv.set("Type_Length_TPID", int("0800", 16)) frame_unv.set("Type_Length", int("0800", 16)) frame_unv.set("Payload", payload) assert frame_unv.valid_message assert frame_unv.bytestring == ethernet_frame_value.bytestring
assert tag_first == 0 and checksum_first_minus_one == 15 second_arg = kwargs.get("Checksum'Last + 1 .. Message'Last") assert isinstance(second_arg, tuple) checksum_last_plus_one, data_last = second_arg assert checksum_last_plus_one == 32 and data_last == 511 checksum_size = kwargs.get("Checksum'Size") assert isinstance(checksum_size, int) assert checksum_size == 16 checksum_bytes = message[tag_first : (checksum_first_minus_one + 1) // 8] checksum_bytes += b"\x00" * (checksum_size // 8) checksum_bytes += message[(checksum_last_plus_one // 8) : (data_last + 1) // 8] return utils.internet_checksum(checksum_bytes) PYRFLX = PyRFLX.from_specs(["specs/ipv4.rflx"], skip_model_verification=True) ICMP = PYRFLX.package("ICMP") ICMP.set_checksum_functions({"Message": {"Checksum": icmp_checksum}}) IP = PYRFLX.package("IPv4") ICMP_DATA = bytes(list(range(0, 56))) def ping(target: str) -> None: target_ip = socket.gethostbyname(target) print(f"PING {target} ({target_ip})") sock_out = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) sock_in = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) fcntl.fcntl(sock_in, fcntl.F_SETFL, os.O_NONBLOCK)
def test_imported_literals(tmp_path: Path) -> None: (tmp_path / "test.rflx").write_text("""-- with Foo; package Test is type T is (E1 => 1, E2 => 2) with Size => 8; type Message is message A : Foo::T then null if A = Foo::E1; end message; end Test;""") (tmp_path / "foo.rflx").write_text("""-- package Foo is type T is (E1 => 11, E2 => 12) with Size => 8; end Foo;""") pyrflx_ = PyRFLX.from_specs([str(tmp_path / "test.rflx")]) m = pyrflx_.package("Test").new_message("Message") m.set("A", "E1") assert m.valid_message m.set("A", "Foo::E1") assert m.valid_message m.parse(b"\x0B") assert m.valid_message assert m.get("A") == "Foo::E1" with pytest.raises( PyRFLXError, match= r"^pyrflx: error: none of the field conditions \['A = Foo::E1'\] for field A have " r"been met by the assigned value: 00001100$", ): m.parse(b"\x0C") assert not m.valid_message with pytest.raises( PyRFLXError, match= r"^pyrflx: error: none of the field conditions \['A = Foo::E1'\] for field A have " r"been met by the assigned value: E2$", ): m.set("A", "E2") assert not m.valid_message with pytest.raises( PyRFLXError, match= r"^pyrflx: error: none of the field conditions \['A = Foo::E1'\] for field A have " r"been met by the assigned value: Foo::E2$", ): m.set("A", "Foo::E2") assert not m.valid_message