def duid_llt(section) -> LinkLayerTimeDUID: """ Create a LinkLayerDUID from the data provided in the config section. :param section: The section data :return: The DUID object """ duid = LinkLayerTimeDUID(hardware_type=section.hardware_type, link_layer_address=section.link_layer_address, time=section.timestamp) duid.validate() return duid
def test_validate_time(self): good_duid_object = LinkLayerTimeDUID(0, 0, b'demo') good_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(0, -1, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 32 bit integer'): bad_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(0, 2 ** 32, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 32 bit integer'): bad_duid_object.validate()
def test_validate_hardware_type(self): good_duid_object = LinkLayerTimeDUID(0, 0, b'demo') good_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(-1, 0, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 16 bit integer'): bad_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(2 ** 16, 0, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 16 bit integer'): bad_duid_object.validate()
def test_validate_length(self): good_duid_object = LinkLayerTimeDUID(0, 0, 120 * b'x') good_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(0, 0, 121 * b'x') with self.assertRaisesRegex(ValueError, 'cannot be longer than 120 bytes'): bad_duid_object.validate()
def test_validate_length(self): good_duid_object = LinkLayerTimeDUID(0, 0, 122 * b'x') good_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(0, 0, 123 * b'x') with self.assertRaisesRegex(ValueError, 'cannot be longer than 122 bytes'): bad_duid_object.validate()
def parse_duid(duid_str: str) -> DUID: """ Parse a string representing a DUID into a real DUID :param duid_str: The string representation :return: The DUID object """ duid_parts = duid_str.split(':') duid_type = duid_parts[0] if duid_type == 'enterprise': if len(duid_parts) == 3: hardware_type = int(duid_parts[1], 10) if duid_parts[2][:2] == '0x': identifier = bytes.fromhex(duid_parts[2][2:]) else: identifier = duid_parts[2].encode('utf-8') return EnterpriseDUID(hardware_type, identifier) else: logger.critical( "Enterprise DUIDs must have format 'enterprise:<enterprise-nr>:<identifier>'" ) raise ValueError elif duid_type == 'linklayer': if len(duid_parts) == 3: hardware_type = int(duid_parts[1], 10) address = bytes.fromhex(duid_parts[2]) return LinkLayerDUID(hardware_type, address) else: logger.critical( "Link Layer DUIDs must have format 'linklayer:<hardware-type>:<address-hex>'" ) raise ValueError elif duid_type == 'linklayer-time': if len(duid_parts) == 4: hardware_type = int(duid_parts[1], 10) timestamp = int(duid_parts[2], 10) address = bytes.fromhex(duid_parts[3]) return LinkLayerTimeDUID(hardware_type, timestamp, address) else: logger.critical( "Link Layer + Time DUIDs must have format " "'linklayer-time:<hardware-type>:<time>:<address-hex>'") raise ValueError else: logger.critical("Unknown DUID type: {}".format(duid_type)) raise ValueError
def setUp(self): # Add a dummy extensions that modifies the marks server_extension_registry['dummy'] = DummyExtension() # Some mock objects to use self.dummy_handler = DeepCopyMagicMock(spec=Handler) unicast_me_filter = MarkedWithFilter( filter_condition='unicast-me', sub_handlers=[ ServerUnicastOptionHandler(address=IPv6Address('2001:db8::1')) ]) ignore_me_filter = MarkedWithFilter( filter_condition='ignore-me', sub_handlers=[IgnoreRequestHandler()]) reject_me_filter = MarkedWithFilter( filter_condition='reject-me', sub_handlers=[BadExceptionHandler()]) # Prove to PyCharm that this is really a handler self.assertIsInstance(self.dummy_handler, Handler) # This is the DUID that is used in the message fixtures self.duid = LinkLayerTimeDUID( hardware_type=1, time=488458703, link_layer_address=bytes.fromhex('00137265ca42')) # Create some message handlers self.message_handler = MessageHandler( server_id=self.duid, sub_filters=[ unicast_me_filter, ignore_me_filter, reject_me_filter ], sub_handlers=[self.dummy_handler], allow_rapid_commit=False, rapid_commit_rejections=False) self.rapid_message_handler = MessageHandler( server_id=self.duid, sub_handlers=[self.dummy_handler], allow_rapid_commit=True, rapid_commit_rejections=False) self.very_rapid_message_handler = MessageHandler( server_id=self.duid, sub_handlers=[self.dummy_handler], allow_rapid_commit=True, rapid_commit_rejections=True)
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')]), ], ) reply_packet = codecs.decode( '07f350d600030028c43cb2f100000000' '000000000005001820010db8ffff0001' '000c00000000e09c0000017700000258' '00190029c43cb2f10000000000000000' '001a001900000177000002583820010d' 'b8ffccfe000000000000000000000100' '0a000300013431c43cb2f10002000e00'
def test_validate_link_layer(self): # noinspection PyTypeChecker bad_duid_object = LinkLayerTimeDUID(0, 0, 'demo') with self.assertRaisesRegex(ValueError, 'sequence of bytes'): bad_duid_object.validate()
def test_validate_time(self): good_duid_object = LinkLayerTimeDUID(0, 0, b'demo') good_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(0, -1, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 32 bit integer'): bad_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(0, 2**32, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 32 bit integer'): bad_duid_object.validate()
def test_validate_hardware_type(self): good_duid_object = LinkLayerTimeDUID(0, 0, b'demo') good_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(-1, 0, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 16 bit integer'): bad_duid_object.validate() bad_duid_object = LinkLayerTimeDUID(2**16, 0, b'demo') with self.assertRaisesRegex(ValueError, 'unsigned 16 bit integer'): bad_duid_object.validate()
def setUp(self): self.duid_object = LinkLayerTimeDUID( hardware_type=1, time=15, link_layer_address=bytes.fromhex('3431c43cb2f1')) self.duid_bytes = bytes.fromhex('000100010000000f3431c43cb2f1')
def test_wrong_parser(self): with self.assertRaisesRegex(ValueError, 'does not contain LinkLayerTimeDUID'): duid = LinkLayerTimeDUID() duid.load_from(self.duid_bytes, length=len(self.duid_bytes))
def setUp(self): # This is the DUID that is used in the message fixtures self.duid = LinkLayerTimeDUID(hardware_type=1, time=488458703, link_layer_address=bytes.fromhex('00137265ca42')) # Create a message handler self.message_handler = MessageHandler(server_id=self.duid)