def test_bad_option_length(self):
        with self.assertRaisesRegex(ValueError, 'embedded message has a different length'):
            LQRelayDataOption.parse(bytes.fromhex(
                '002f'  # Option type: OPTION_LQ_RELAY_DATA
                '003a'  # Option length: 58 (should be 59)
                '20010db8000000000000000000000002'  # Peer address: 2001:db8::2

                '0c'  # Message type: MSG_RELAY_FORW
                '00'  # Hop count: 0
                '20010db8000000000000000000000002'  # Link address: 2001:db8::2
                'fe800000000000000000000000000022'  # Peer address: fe80::22

                '0012'  # Option type: OPTION_INTERFACE_ID
                '0005'  # Option length: 5
                '4661322f33'  # Interface ID: 'Fa2/3'
            ))

        with self.assertRaisesRegex(ValueError, 'longer than the available buffer'):
            LQRelayDataOption.parse(bytes.fromhex(
                '002f'  # Option type: OPTION_LQ_RELAY_DATA
                '003c'  # Option length: 60 (should be 59)
                '20010db8000000000000000000000002'  # Peer address: 2001:db8::2

                '0c'  # Message type: MSG_RELAY_FORW
                '00'  # Hop count: 0
                '20010db8000000000000000000000002'  # Link address: 2001:db8::2
                'fe800000000000000000000000000022'  # Peer address: fe80::22

                '0012'  # Option type: OPTION_INTERFACE_ID
                '0005'  # Option length: 5
                '4661322f33'  # Interface ID: 'Fa2/3'
            ))
    def test_bad_option_length(self):
        with self.assertRaisesRegex(ValueError, "embedded message has a different length"):
            LQRelayDataOption.parse(
                bytes.fromhex(
                    "002f"  # Option type: OPTION_LQ_RELAY_DATA
                    "003a"  # Option length: 58 (should be 59)
                    "20010db8000000000000000000000002"  # Peer address: 2001:db8::2
                    "0c"  # Message type: MSG_RELAY_FORW
                    "00"  # Hop count: 0
                    "20010db8000000000000000000000002"  # Link address: 2001:db8::2
                    "fe800000000000000000000000000022"  # Peer address: fe80::22
                    "0012"  # Option type: OPTION_INTERFACE_ID
                    "0005"  # Option length: 5
                    "4661322f33"  # Interface ID: 'Fa2/3'
                )
            )

        with self.assertRaisesRegex(ValueError, "longer than the available buffer"):
            LQRelayDataOption.parse(
                bytes.fromhex(
                    "002f"  # Option type: OPTION_LQ_RELAY_DATA
                    "003c"  # Option length: 60 (should be 59)
                    "20010db8000000000000000000000002"  # Peer address: 2001:db8::2
                    "0c"  # Message type: MSG_RELAY_FORW
                    "00"  # Hop count: 0
                    "20010db8000000000000000000000002"  # Link address: 2001:db8::2
                    "fe800000000000000000000000000022"  # Peer address: fe80::22
                    "0012"  # Option type: OPTION_INTERFACE_ID
                    "0005"  # Option length: 5
                    "4661322f33"  # Interface ID: 'Fa2/3'
                )
            )
    def test_test_wrong_message(self):
        with self.assertRaisesRegex(ValueError, 'must be an IPv6 DHCP message'):
            LQRelayDataOption(
                peer_address=IPv6Address('2001:db8::2'),
                relay_message=None
            ).validate()

        with self.assertRaisesRegex(ValueError, 'cannot contain'):
            # noinspection PyTypeChecker
            LQRelayDataOption(
                peer_address=IPv6Address('2001:db8::2'),
                relay_message=SolicitMessage()
            ).validate()
    def setUp(self):
        self.option_bytes = bytes.fromhex(
            '002f'  # Option type: OPTION_LQ_RELAY_DATA
            '003b'  # Option length: 59
            '20010db8000000000000000000000002'  # Peer address: 2001:db8::2

            '0c'  # Message type: MSG_RELAY_FORW
            '00'  # Hop count: 0
            '20010db8000000000000000000000002'  # Link address: 2001:db8::2
            'fe800000000000000000000000000022'  # Peer address: fe80::22

            '0012'  # Option type: OPTION_INTERFACE_ID
            '0005'  # Option length: 5
            '4661322f33'  # Interface ID: 'Fa2/3'
        )
        self.option_object = LQRelayDataOption(
            peer_address=IPv6Address('2001:db8::2'),
            relay_message=RelayForwardMessage(
                hop_count=0,
                link_address=IPv6Address('2001:db8::2'),
                peer_address=IPv6Address('fe80::22'),
                options=[
                    InterfaceIdOption(interface_id=b'Fa2/3'),
                ]
            )
        )

        self.parse_option()
Exemple #5
0
    def build_relay_data_option_from_relay_data(
            self, relay_data: bytes) -> Optional[LQRelayDataOption]:
        """
        The relay data includes the outer relay message, which is generated inside the server to keep track of where
        we got the request from. When returning relay data to the leasequery client we build the LQRelayDataOption
        using this internal relay message only including the real relay messages we received.

        :param relay_data: The raw relay data
        :return: The LQRelayDataOption if applicable
        """
        if not relay_data:
            return None

        relay_chain = self.decode_relay_messages(relay_data)

        # The outer relay message contains the peer address we need
        peer_address = relay_chain.peer_address

        # Go up one position in the relay chain
        relay_chain = relay_chain.relayed_message

        if not isinstance(relay_chain, RelayForwardMessage):
            # We only had the internal relay message, so we didn't receive this client's request through a relay
            return None

        return LQRelayDataOption(peer_address, relay_chain)
    def setUp(self):
        self.option_bytes = bytes.fromhex(
            '002d'  # Option type 45: OPTION_CLIENT_DATA
            '0099'  # Option length: 153

            '0001'  # Option type 1: OPTION_CLIENT_ID
            '0015'  # Option length: 21
            '0002'  # DUID type: DUID_EN
            '00009d10'  # Enterprise ID: 40208
            '303132333435363738396162636465'  # Identifier: '0123456789abcde'

            '0005'  # Option type: OPTION_IAADDR
            '0018'  # Option length: 24
            '20010db800000000000000000000cafe'  # IPv6 address: 2001:db8::cafe
            '00000708'  # Preferred lifetime: 1800
            '00000e10'  # Valid lifetime: 3600

            '001a'  # Option type: OPTION_IAPREFIX
            '0019'  # Option length: 25
            '00000708'  # Preferred lifetime: 1800
            '00000e10'  # Valid lifetime: 3600
            '30'  # Prefix length: 48
            '20010db8000100000000000000000000'

            '002e'  # Option type: OPTION_CLT_TIME
            '0004'  # Option length: 4
            '00000384'  # Client-Last-Transaction time: 900

            '002f'  # Option type: OPTION_LQ_RELAY_DATA
            '003b'  # Option length: 59
            '20010db8000000000000000000000002'  # Peer address: 2001:db8::2

            '0c'  # Message type: MSG_RELAY_FORW
            '00'  # Hop count: 0
            '20010db8000000000000000000000002'  # Link address: 2001:db8::2
            'fe800000000000000000000000000022'  # Peer address: fe80::22

            '0012'  # Option type: OPTION_INTERFACE_ID
            '0005'  # Option length: 5
            '4661322f33'  # Interface ID: 'Fa2/3'
        )
        self.option_object = ClientDataOption(options=[
            ClientIdOption(EnterpriseDUID(40208, b'0123456789abcde')),
            IAAddressOption(address=IPv6Address('2001:db8::cafe'), preferred_lifetime=1800, valid_lifetime=3600),
            IAPrefixOption(prefix=IPv6Network('2001:db8:1::/48'), preferred_lifetime=1800, valid_lifetime=3600),
            CLTTimeOption(clt_time=900),
            LQRelayDataOption(peer_address=IPv6Address('2001:db8::2'), relay_message=RelayForwardMessage(
                hop_count=0,
                link_address=IPv6Address('2001:db8::2'),
                peer_address=IPv6Address('fe80::22'),
                options=[
                    InterfaceIdOption(interface_id=b'Fa2/3'),
                ]
            ))
        ])

        self.parse_option()
    def test_bad_option_length(self):
        with self.assertRaisesRegex(ValueError, 'length does not match the combined length'):
            LQRelayDataOption.parse(bytes.fromhex(
                '0030'  # Option type: OPTION_LQ_CLIENT_LINK
                '002f'  # Option length: 47 (should be 48)
                '20010db8000000000000000000000001'  # Link address: 2001:db8::2
                '20010db8000000000000000000000002'  # Link address: 2001:db8::2
                '20010db8000000000000000000000004'  # Link address: 2001:db8::2
            ))

        with self.assertRaisesRegex(ValueError, 'longer than the available buffer'):
            LQRelayDataOption.parse(bytes.fromhex(
                '0030'  # Option type: OPTION_LQ_CLIENT_LINK
                '0031'  # Option length: 49 (should be 48)
                '20010db8000000000000000000000001'  # Link address: 2001:db8::2
                '20010db8000000000000000000000002'  # Link address: 2001:db8::2
                '20010db8000000000000000000000004'  # Link address: 2001:db8::2
            ))
Exemple #8
0
    def test_bad_option_length(self):
        with self.assertRaisesRegex(
                ValueError, 'length does not match the combined length'):
            LQRelayDataOption.parse(
                bytes.fromhex(
                    '0030'  # Option type: OPTION_LQ_CLIENT_LINK
                    '002f'  # Option length: 47 (should be 48)
                    '20010db8000000000000000000000001'  # Link address: 2001:db8::2
                    '20010db8000000000000000000000002'  # Link address: 2001:db8::2
                    '20010db8000000000000000000000004'  # Link address: 2001:db8::2
                ))

        with self.assertRaisesRegex(ValueError,
                                    'longer than the available buffer'):
            LQRelayDataOption.parse(
                bytes.fromhex(
                    '0030'  # Option type: OPTION_LQ_CLIENT_LINK
                    '0031'  # Option length: 49 (should be 48)
                    '20010db8000000000000000000000001'  # Link address: 2001:db8::2
                    '20010db8000000000000000000000002'  # Link address: 2001:db8::2
                    '20010db8000000000000000000000004'  # Link address: 2001:db8::2
                ))
 def test_parse_wrong_type(self):
     with self.assertRaisesRegex(ValueError, 'does not contain LQRelayDataOption data'):
         option = LQRelayDataOption()
         option.load_from(b'00020010ff12000000000000000000000000abcd')
 def test_parse_wrong_type(self):
     with self.assertRaisesRegex(ValueError, "does not contain LQRelayDataOption data"):
         option = LQRelayDataOption()
         option.load_from(b"00020010ff12000000000000000000000000abcd")