Пример #1
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(),
     ]
Пример #2
0
    def test_bad_option_length(self):
        with self.assertRaisesRegex(ValueError,
                                    'shorter than the minimum length'):
            IAPDOption.parse(bytes.fromhex('0019000041424344000000290000002a'))

        with self.assertRaisesRegex(ValueError, 'length does not match'):
            IAPDOption.parse(
                bytes.fromhex('0019000d41424344000000290000002a00140000'))
Пример #3
0
 def setUp(self):
     self.option_bytes = bytes.fromhex(
         '0019'  # option_type: OPTION_IA_PD
         '0045'  # option_length
         '41424344'  # iaid: ABCD
         '00000029'  # t1: 41
         '0000002a'  # t2: 42
         '001a'  # option_type: OPTION_IAPREFIX
         '0019'  # option_length
         '00000000'  # preferred_lifetime
         '00000000'  # valid_lifetime
         '30'  # prefix_length: 48
         '20010db8000000000000000000000000'  # prefix: 2001:db8::
         '000d'  # option_type: OPTION_STATUS_CODE
         '0018'  # option_length
         '0000'  # status_code
         '45766572797468696e6720697320617765736f6d6521')  # status_message
     self.option_object = IAPDOption(
         iaid=b'ABCD',
         t1=41,
         t2=42,
         options=[
             IAPrefixOption(prefix=IPv6Network('2001:db8::/48')),
             StatusCodeOption(status_code=STATUS_SUCCESS,
                              status_message='Everything is awesome!')
         ])
     self.parse_option()
Пример #4
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'))),
         ],
     )
Пример #5
0
    def handle_request(self, bundle: TransactionBundle):
        """
        Handle a client requesting addresses (also handles SolicitMessage)

        :param bundle: The request bundle
        """
        # Get the assignment
        assignment = self.get_assignment(bundle)

        # Try to assign the prefix first: it's not dependent on the link
        if assignment.prefix:
            unanswered_iapd_options = bundle.get_unhandled_options(IAPDOption)
            found_option = self.find_iapd_option_for_prefix(
                unanswered_iapd_options, assignment.prefix)
            if found_option:
                # Answer to this option
                logger.log(DEBUG_HANDLING,
                           "Assigning prefix {}".format(assignment.prefix))
                response_option = IAPDOption(
                    found_option.iaid,
                    options=[
                        IAPrefixOption(
                            prefix=assignment.prefix,
                            preferred_lifetime=self.prefix_preferred_lifetime,
                            valid_lifetime=self.prefix_valid_lifetime)
                    ])
                bundle.response.options.append(response_option)
                bundle.mark_handled(found_option)
            else:
                logger.log(
                    DEBUG_HANDLING,
                    "Prefix {} reserved, but client did not ask for it".format(
                        assignment.prefix))

        if assignment.address:
            unanswered_iana_options = bundle.get_unhandled_options(IANAOption)
            found_option = self.find_iana_option_for_address(
                unanswered_iana_options, assignment.address)
            if found_option:
                # Answer to this option
                logger.log(DEBUG_HANDLING,
                           "Assigning address {}".format(assignment.address))
                response_option = IANAOption(
                    found_option.iaid,
                    options=[
                        IAAddressOption(
                            address=assignment.address,
                            preferred_lifetime=self.address_preferred_lifetime,
                            valid_lifetime=self.address_valid_lifetime)
                    ])
                bundle.response.options.append(response_option)
                bundle.mark_handled(found_option)
            else:
                logger.log(
                    DEBUG_HANDLING,
                    "Address {} reserved, but client did not ask for it".
                    format(assignment.address))
Пример #6
0
#          1 DNS server address: 2001:4860:4860::8888 (2001:4860:4860::8888)

reply_message = ReplyMessage(
    transaction_id=bytes.fromhex('f350d6'),
    options=[
        IANAOption(iaid=bytes.fromhex('c43cb2f1'),
                   options=[
                       IAAddressOption(
                           address=IPv6Address('2001:db8:ffff:1:c::e09c'),
                           preferred_lifetime=375,
                           valid_lifetime=600),
                   ]),
        IAPDOption(iaid=bytes.fromhex('c43cb2f1'),
                   options=[
                       IAPrefixOption(
                           prefix=IPv6Network('2001:db8:ffcc:fe00::/56'),
                           preferred_lifetime=375,
                           valid_lifetime=600),
                   ]),
        ClientIdOption(duid=LinkLayerDUID(hardware_type=1,
                                          link_layer_address=bytes.fromhex(
                                              '3431c43cb2f1'))),
        ServerIdOption(duid=LinkLayerTimeDUID(hardware_type=1,
                                              time=488458703,
                                              link_layer_address=bytes.fromhex(
                                                  '00137265ca42'))),
        ReconfigureAcceptOption(),
        RecursiveNameServersOption(
            dns_servers=[IPv6Address('2001:4860:4860::8888')]),
    ],
)
Пример #7
0
 def test_unanswered_iapd_options(self):
     unanswered_options = self.ia_bundle.get_unhandled_options(IAPDOption)
     self.assertEqual(len(unanswered_options), 2)
     self.assertIn(IAPDOption(b'0005'), unanswered_options)
     self.assertIn(IAPDOption(b'0006'), unanswered_options)
Пример #8
0
 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),
         ],
Пример #9
0
        # Prefix length
        self.prefix_length = buffer[offset + my_offset]
        my_offset += 1

        # Subnet-ID
        subnet_id_length = option_len - 1
        self.subnet_id = buffer[offset + my_offset:offset + my_offset +
                                subnet_id_length]
        my_offset += subnet_id_length

        return my_offset

    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        buffer = bytearray()
        buffer.extend(
            pack('!HHB', self.option_type, 1 + len(self.subnet_id),
                 self.prefix_length))
        buffer.extend(self.subnet_id)

        return buffer


# Register where these options may occur
IAPDOption.add_may_contain(PDExcludeOption, 0, 1)
Пример #10
0
    def handle_renew_rebind(self, bundle: TransactionBundle):
        """
        Handle a client renewing/rebinding addresses

        :param bundle: The request bundle
        """
        # Get the assignment
        assignment = self.get_assignment(bundle)

        # Collect unanswered options
        unanswered_iana_options = bundle.get_unhandled_options(IANAOption)
        unanswered_iapd_options = bundle.get_unhandled_options(IAPDOption)

        for option in unanswered_iapd_options:
            if assignment.prefix and prefix_overlaps_prefixes(
                    assignment.prefix, option.get_prefixes()):
                # Overlap with our assigned prefix: take responsibility
                response_suboptions = []
                for suboption in option.get_options_of_type(IAPrefixOption):
                    if suboption.prefix == assignment.prefix:
                        # This is the correct option, renew it
                        logger.log(
                            DEBUG_HANDLING,
                            "Renewing prefix {}".format(assignment.prefix))
                        response_suboptions.append(
                            IAPrefixOption(
                                prefix=assignment.prefix,
                                preferred_lifetime=self.
                                prefix_preferred_lifetime,
                                valid_lifetime=self.prefix_valid_lifetime))
                    else:
                        # This isn't right
                        logger.log(
                            DEBUG_HANDLING,
                            "Withdrawing prefix {}".format(suboption.prefix))
                        response_suboptions.append(
                            IAPrefixOption(prefix=suboption.prefix,
                                           preferred_lifetime=0,
                                           valid_lifetime=0))

                response_option = IAPDOption(option.iaid,
                                             options=response_suboptions)
                bundle.response.options.append(response_option)
                bundle.mark_handled(option)

        for option in unanswered_iana_options:
            response_suboptions = []
            for suboption in option.get_options_of_type(IAAddressOption):
                if suboption.address == assignment.address:
                    # This is the correct option, renew it
                    logger.log(
                        DEBUG_HANDLING,
                        "Renewing address {}".format(assignment.address))
                    response_suboptions.append(
                        IAAddressOption(
                            address=assignment.address,
                            preferred_lifetime=self.address_preferred_lifetime,
                            valid_lifetime=self.address_valid_lifetime))
                else:
                    # This isn't right
                    logger.log(
                        DEBUG_HANDLING,
                        "Withdrawing address {}".format(suboption.address))
                    response_suboptions.append(
                        IAAddressOption(address=suboption.address,
                                        preferred_lifetime=0,
                                        valid_lifetime=0))

            response_option = IANAOption(option.iaid,
                                         options=response_suboptions)
            bundle.response.options.append(response_option)
            bundle.mark_handled(option)
    def test_bad_option_length(self):
        with self.assertRaisesRegex(ValueError, 'shorter than the minimum length'):
            IAPDOption.parse(bytes.fromhex('0019000041424344000000290000002a'))

        with self.assertRaisesRegex(ValueError, 'length does not match'):
            IAPDOption.parse(bytes.fromhex('0019000d41424344000000290000002a00140000'))