Beispiel #1
0
 def setUp(self):
     self.relayed_solicit_message = RelayForwardMessage(
         hop_count=1,
         link_address=IPv6Address('2001:db8:ffff:1::1'),
         peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
         options=[
             RelayMessageOption(relayed_message=RelayForwardMessage(
                 hop_count=0,
                 link_address=IPv6Address('::'),
                 peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
                 options=[
                     RelayMessageOption(relayed_message=SolicitMessage(
                         transaction_id=bytes.fromhex('f350d6'),
                         options=[
                             ElapsedTimeOption(elapsed_time=0),
                             ClientIdOption(duid=LinkLayerDUID(hardware_type=1,
                                                               link_layer_address=bytes.fromhex('3431c43cb2f1'))),
                             IANAOption(iaid=bytes.fromhex('c43cb2f1')),
                             IAPDOption(iaid=bytes.fromhex('c43cb2f1')),
                             OptionRequestOption(requested_options=[
                                 OPTION_DNS_SERVERS,
                             ]),
                         ],
                     )),
                     InterfaceIdOption(interface_id=b'Fa2/3'),
                     RemoteIdOption(enterprise_number=9,
                                    remote_id=bytes.fromhex('020023000001000a0003000100211c7d486e')),
                 ])
             ),
             InterfaceIdOption(interface_id=b'Gi0/0/0'),
             RemoteIdOption(enterprise_number=9, remote_id=bytes.fromhex('020000000000000a0003000124e9b36e8100')),
             RelayIdOption(duid=LinkLayerDUID(hardware_type=1, link_layer_address=bytes.fromhex('121212121212'))),
         ],
     )
Beispiel #2
0
    def setUp(self):
        # The following attributes must be overruled by child classes
        # The basics are tested with nested RelayForwardMessages
        self.packet_fixture = bytes.fromhex(
            '0c'  # message_type: MSG_RELAY_FORW
            '02'  # hop_count
            '20010db8000000000000000000020001'  # link_address
            '20010db8000000000000000000020002'  # peer_address
            '0009'  # option_type: OPTION_RELAY_MSG
            '0051'  # option_length
            '0c'  # message_type: MSG_RELAY_FORW
            '01'  # hop_count
            '20010db8000000000000000000010001'  # link_address
            '20010db8000000000000000000010002'  # peer_address
            '0009'  # option_type: OPTION_RELAY_MSG
            '002b'  # option_length
            '0c'  # message_type: MSG_RELAY_FORW
            '00'  # hop_count
            '20010db8000000000000000000000001'  # link_address
            '20010db8000000000000000000000002'  # peer_address
            '0009'  # option_type: OPTION_RELAY_MSG
            '0005'  # option_length
            'ff'  # some unknown  message_type: 255
            '41424344')  # some random message_data: 'ABCD'

        self.message_fixture = RelayForwardMessage(
            hop_count=2,
            link_address=IPv6Address('2001:db8::2:1'),
            peer_address=IPv6Address('2001:db8::2:2'),
            options=[
                RelayMessageOption(relayed_message=RelayForwardMessage(
                    hop_count=1,
                    link_address=IPv6Address('2001:db8::1:1'),
                    peer_address=IPv6Address('2001:db8::1:2'),
                    options=[
                        RelayMessageOption(relayed_message=RelayForwardMessage(
                            hop_count=0,
                            link_address=IPv6Address('2001:db8::1'),
                            peer_address=IPv6Address('2001:db8::2'),
                            options=[
                                RelayMessageOption(
                                    relayed_message=UnknownMessage(
                                        255, b'ABCD'))
                            ]))
                    ]))
            ])

        self.parse_packet()
    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()
    def test_absent_option_echo_request(self):
        relayed_solicit_message = RelayForwardMessage(
            hop_count=1,
            link_address=IPv6Address('2001:db8:ffff:1::1'),
            peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
            options=[
                RelayMessageOption(relayed_message=SolicitMessage(
                    transaction_id=bytes.fromhex('f350d6'),
                    options=[
                        ElapsedTimeOption(elapsed_time=0),
                        ClientIdOption(duid=LinkLayerDUID(hardware_type=1,
                                                          link_layer_address=bytes.fromhex('3431c43cb2f1'))),
                        IANAOption(iaid=bytes.fromhex('c43cb2f1')),
                    ],
                )),
                EchoRequestOption(requested_options=[OPTION_SUBSCRIBER_ID]),
                UnknownOption(option_type=65535),
                InterfaceIdOption(interface_id=b'Fa2/3'),
                RemoteIdOption(enterprise_number=9,
                               remote_id=bytes.fromhex('020023000001000a0003000100211c7d486e')),
            ]
        )

        bundle = TransactionBundle(incoming_message=relayed_solicit_message, received_over_multicast=True)
        self.message_handler.handle(bundle, StatisticsSet())

        self.assertIsInstance(bundle.outgoing_message, RelayReplyMessage)
        self.assertEqual(len(bundle.outgoing_message.options), 2)
        self.assertIsInstance(bundle.outgoing_message.options[0], InterfaceIdOption)
        self.assertIsInstance(bundle.outgoing_message.options[1], RelayMessageOption)
Beispiel #5
0
    def encode_relay_messages(
            self, relay_chain: Optional[RelayForwardMessage]) -> bytes:
        """
        Encode a chain of relay messages as bytes.

        :param relay_chain: The incoming relay messages
        :return: The bytes
        """
        if not relay_chain:
            return b''

        current_in = relay_chain
        current_out = None
        out = None
        while isinstance(current_in, RelayForwardMessage):
            new_relay_message = RelayForwardMessage(
                hop_count=current_in.hop_count,
                link_address=current_in.link_address,
                peer_address=current_in.peer_address,
                options=self.filter_storable_options(current_in.options))
            if not current_out:
                out = new_relay_message
            else:
                current_out.relayed_message = new_relay_message

            current_in = current_in.relayed_message
            current_out = new_relay_message

        # Save the resulting chain
        if not out:
            return b''

        return out.save()
Beispiel #6
0
 def setUp(self):
     self.bundle = TransactionBundle(relayed_solicit_message,
                                     received_over_multicast=False)
     self.shallow_bundle = TransactionBundle(solicit_message,
                                             received_over_multicast=True)
     self.deep_bundle = TransactionBundle(RelayForwardMessage(
         hop_count=0,
         link_address=IPv6Address('2001:db8:ffff:2::1'),
         peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
         options=[
             RelayMessageOption(relayed_message=relayed_solicit_message),
         ]),
                                          received_over_multicast=False,
                                          marks=['some', 'marks'])
     self.ia_bundle = TransactionBundle(SolicitMessage(options=[
         IANAOption(b'0001'),
         IANAOption(b'0002'),
         IATAOption(b'0003'),
         IATAOption(b'0004'),
         IAPDOption(b'0005'),
         IAPDOption(b'0006'),
     ]),
                                        received_over_multicast=False)
     self.option_handlers = [
         InterfaceIdOptionHandler(),
     ]
    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()
Beispiel #8
0
    def test_empty_message(self):
        with self.assertLogs(level=logging.WARNING) as cm:
            bundle = TransactionBundle(incoming_message=RelayForwardMessage(),
                                       received_over_multicast=True)
            result = self.message_handler.handle(bundle, StatisticsSet())
            self.assertIsNone(result)

        self.assertEqual(len(cm.output), 1)
        self.assertRegex(cm.output[0],
                         '^WARNING:.*:A server should not receive')
Beispiel #9
0
def parse_incoming_request(
        incoming_packet: IncomingPacketBundle) -> TransactionBundle:
    """
    Parse the incoming packet and add a RelayServerMessage around it containing the meta-data received from the
    listener.

    :param incoming_packet: The received packet
    :return: The parsed message in a transaction bundle
    """
    # Parse message and validate
    length, incoming_message = Message.parse(incoming_packet.data)
    incoming_message.validate()

    # Determine the next hop count and construct useful log messages
    if isinstance(incoming_message, RelayForwardMessage):
        next_hop_count = incoming_message.hop_count + 1
    else:
        next_hop_count = 0

    # Collect the relay options
    relay_options = []
    """:type: List[Option]"""

    relay_options.append(
        InterfaceIdOption(
            interface_id=incoming_packet.interface_name.encode('utf-8')))
    relay_options.extend(incoming_packet.extra_options)
    relay_options.append(RelayMessageOption(relayed_message=incoming_message))

    # Pretend to be an internal relay and wrap the message like a relay would
    wrapped_message = RelayForwardMessage(
        hop_count=next_hop_count,
        link_address=incoming_packet.link_address,
        peer_address=incoming_packet.sender,
        options=relay_options)

    # Create the transaction bundle
    return TransactionBundle(
        incoming_message=wrapped_message,
        received_over_multicast=incoming_packet.received_over_multicast,
        marks=incoming_packet.marks)
Beispiel #10
0
relayed_solicit_message = RelayForwardMessage(
    hop_count=1,
    link_address=IPv6Address('2001:db8:ffff:1::1'),
    peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
    options=[
        RelayMessageOption(relayed_message=RelayForwardMessage(
            hop_count=0,
            link_address=IPv6Address('::'),
            peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
            options=[
                RelayMessageOption(relayed_message=SolicitMessage(
                    transaction_id=bytes.fromhex('f350d6'),
                    options=[
                        ElapsedTimeOption(elapsed_time=0),
                        ClientIdOption(duid=LinkLayerDUID(
                            hardware_type=1,
                            link_layer_address=bytes.fromhex('3431c43cb2f1'))),
                        RapidCommitOption(),
                        IANAOption(iaid=bytes.fromhex('c43cb2f1')),
                        IAPDOption(iaid=bytes.fromhex('c43cb2f1'),
                                   options=[
                                       IAPrefixOption(
                                           prefix=IPv6Network('::/0')),
                                   ]),
                        ReconfigureAcceptOption(),
                        OptionRequestOption(requested_options=[
                            OPTION_DNS_SERVERS,
                            OPTION_NTP_SERVER,
                            OPTION_SNTP_SERVERS,
                            OPTION_IA_PD,
                            OPTION_IA_NA,
                            OPTION_VENDOR_OPTS,
                            OPTION_SOL_MAX_RT,
                            OPTION_INF_MAX_RT,
                        ]),
                        VendorClassOption(enterprise_number=872),
                    ],
                )),
                InterfaceIdOption(interface_id=b'Fa2/3'),
                RemoteIdOption(enterprise_number=9,
                               remote_id=bytes.fromhex(
                                   '020023000001000a0003000100211c7d486e')),
            ])),
        InterfaceIdOption(interface_id=b'Gi0/0/0'),
        RemoteIdOption(
            enterprise_number=9,
            remote_id=bytes.fromhex('020000000000000a0003000124e9b36e8100')),
    ],
)