dhcpkit.ipv6.duids module

Classes and constants for the DUIDs defined in RFC 3315

class dhcpkit.ipv6.duids.DUID[source]

Bases: dhcpkit.protocol_element.ProtocolElement

RFC 3315#section-9.1

A DUID consists of a two-octet type code represented in network byte order, followed by a variable number of octets that make up the actual identifier. A DUID can be no more than 128 octets long (not including the type code).

classmethod determine_class(buffer: bytes, offset: int = 0) → type[source]

Return the appropriate subclass from the registry, or UnknownDUID if no subclass is registered.

Parameters:
  • buffer – The buffer to read data from
  • offset – The offset in the buffer where to start reading
Returns:

The best known class for this duid data

duid_type = 0
parse_duid_header(buffer: bytes, offset: int = 0, length: int = None) → int[source]

Parse the DUID type and perform some basic validation.

Parameters:
  • buffer – The buffer to read data from
  • offset – The offset in the buffer where to start reading
  • length – The amount of data we are allowed to read from the buffer
Returns:

The number of bytes used from the buffer

class dhcpkit.ipv6.duids.EnterpriseDUID(enterprise_number: int = 0, identifier: bytes = b'')[source]

Bases: dhcpkit.ipv6.duids.DUID

RFC 3315#section-9.3

This form of DUID is assigned by the vendor to the device. It consists of the vendor’s registered Private Enterprise Number as maintained by IANA [6] followed by a unique identifier assigned by the vendor. The following diagram summarizes the structure of a DUID-EN:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               2               |       enterprise-number       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   enterprise-number (contd)   |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
.                           identifier                          .
.                       (variable length)                       .
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The source of the identifier is left up to the vendor defining it, but each identifier part of each DUID-EN MUST be unique to the device that is using it, and MUST be assigned to the device at the time it is manufactured and stored in some form of non-volatile storage. The generated DUID SHOULD be recorded in non-erasable storage. The enterprise-number is the vendor’s registered Private Enterprise Number as maintained by IANA [6]. The enterprise-number is stored as an unsigned 32 bit number.

An example DUID of this type might look like this:

+---+---+---+---+---+---+---+---+
| 0 | 2 | 0 | 0 | 0 |  9| 12|192|
+---+---+---+---+---+---+---+---+
|132|221| 3 | 0 | 9 | 18|
+---+---+---+---+---+---+

This example includes the two-octet type of 2, the Enterprise Number (9), followed by eight octets of identifier data (0x0CC084D303000912).

duid_type = 2
load_from(buffer: bytes, offset: int = 0, length: int = None) → int[source]

Load the internal state of this object from the given buffer. The buffer may contain more data after the structured element is parsed. This data is ignored.

Parameters:
  • buffer – The buffer to read data from
  • offset – The offset in the buffer where to start reading
  • length – The amount of data we are allowed to read from the buffer
Returns:

The number of bytes used from the buffer

save() → Union[source]

Save the internal state of this object as a buffer.

Returns:The buffer with the data from this element
validate()[source]

Validate that the contents of this object conform to protocol specs.

class dhcpkit.ipv6.duids.LinkLayerDUID(hardware_type: int = 0, link_layer_address: bytes = b'')[source]

Bases: dhcpkit.ipv6.duids.DUID

RFC 3315#section-9.4

This type of DUID consists of two octets containing the DUID type 3, a two octet network hardware type code, followed by the link-layer address of any one network interface that is permanently connected to the client or server device. For example, a host that has a network interface implemented in a chip that is unlikely to be removed and used elsewhere could use a DUID-LL. The hardware type MUST be a valid hardware type assigned by the IANA, as described in RFC 826 [14]. The hardware type is stored in network byte order. The link-layer address is stored in canonical form, as described in RFC 2464 [2]. The following diagram illustrates the format of a DUID-LL:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               3               |    hardware type (16 bits)    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                                                               .
.             link-layer address (variable length)              .
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The choice of network interface can be completely arbitrary, as long as that interface provides a unique link-layer address and is permanently attached to the device on which the DUID-LL is being generated. The same DUID-LL SHOULD be used in configuring all network interfaces connected to the device, regardless of which interface’s link-layer address was used to generate the DUID.

DUID-LL is recommended for devices that have a permanently-connected network interface with a link-layer address, and do not have nonvolatile, writable stable storage. DUID-LL MUST NOT be used by DHCP clients or servers that cannot tell whether or not a network interface is permanently attached to the device on which the DHCP client is running.

display_hardware_type() → dhcpkit.protocol_element.ElementDataRepresentation[source]

Nicer representation of hardware types :return: Representation of hardware type

Nicer representation of link-layer address if we know the hardware type :return: Representation of link-layer address

duid_type = 3
load_from(buffer: bytes, offset: int = 0, length: int = None) → int[source]

Load the internal state of this object from the given buffer. The buffer may contain more data after the structured element is parsed. This data is ignored.

Parameters:
  • buffer – The buffer to read data from
  • offset – The offset in the buffer where to start reading
  • length – The amount of data we are allowed to read from the buffer
Returns:

The number of bytes used from the buffer

save() → Union[source]

Save the internal state of this object as a buffer.

Returns:The buffer with the data from this element
validate()[source]

Validate that the contents of this object conform to protocol specs.

class dhcpkit.ipv6.duids.LinkLayerTimeDUID(hardware_type: int = 0, time: int = 0, link_layer_address: bytes = b'')[source]

Bases: dhcpkit.ipv6.duids.DUID

RFC 3315#section-9.2

This type of DUID consists of a two octet type field containing the value 1, a two octet hardware type code, four octets containing a time value, followed by link-layer address of any one network interface that is connected to the DHCP device at the time that the DUID is generated. The time value is the time that the DUID is generated represented in seconds since midnight (UTC), January 1, 2000, modulo 2^32. The hardware type MUST be a valid hardware type assigned by the IANA as described in RFC 826 [14]. Both the time and the hardware type are stored in network byte order. The link-layer address is stored in canonical form, as described in RFC 2464 [2].

The following diagram illustrates the format of a DUID-LLT:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               1               |    hardware type (16 bits)    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        time (32 bits)                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                                                               .
.             link-layer address (variable length)              .
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The choice of network interface can be completely arbitrary, as long as that interface provides a globally unique link-layer address for the link type, and the same DUID-LLT SHOULD be used in configuring all network interfaces connected to the device, regardless of which interface’s link-layer address was used to generate the DUID-LLT.

Clients and servers using this type of DUID MUST store the DUID-LLT in stable storage, and MUST continue to use this DUID-LLT even if the network interface used to generate the DUID-LLT is removed. Clients and servers that do not have any stable storage MUST NOT use this type of DUID.

Clients and servers that use this DUID SHOULD attempt to configure the time prior to generating the DUID, if that is possible, and MUST use some sort of time source (for example, a real-time clock) in generating the DUID, even if that time source could not be configured prior to generating the DUID. The use of a time source makes it unlikely that two identical DUID-LLTs will be generated if the network interface is removed from the client and another client then uses the same network interface to generate a DUID-LLT. A collision between two DUID-LLTs is very unlikely even if the clocks have not been configured prior to generating the DUID.

This method of DUID generation is recommended for all general purpose computing devices such as desktop computers and laptop computers, and also for devices such as printers, routers, and so on, that contain some form of writable non-volatile storage.

Despite our best efforts, it is possible that this algorithm for generating a DUID could result in a client identifier collision. A DHCP client that generates a DUID-LLT using this mechanism MUST provide an administrative interface that replaces the existing DUID with a newly-generated DUID-LLT.

display_hardware_type() → dhcpkit.protocol_element.ElementDataRepresentation[source]

Nicer representation of hardware types :return: Representation of hardware type

Nicer representation of link-layer address if we know the hardware type :return: Representation of link-layer address

duid_type = 1
load_from(buffer: bytes, offset: int = 0, length: int = None) → int[source]

Load the internal state of this object from the given buffer. The buffer may contain more data after the structured element is parsed. This data is ignored.

Parameters:
  • buffer – The buffer to read data from
  • offset – The offset in the buffer where to start reading
  • length – The amount of data we are allowed to read from the buffer
Returns:

The number of bytes used from the buffer

save() → Union[source]

Save the internal state of this object as a buffer.

Returns:The buffer with the data from this element
validate()[source]

Validate that the contents of this object conform to protocol specs.

class dhcpkit.ipv6.duids.UnknownDUID(duid_type: int = 0, duid_data: bytes = b'')[source]

Bases: dhcpkit.ipv6.duids.DUID

Container for raw DUID content for cases where we don’t know how to decode the DUID.

load_from(buffer: bytes, offset: int = 0, length: int = None) → int[source]

Load the internal state of this object from the given buffer. The buffer may contain more data after the structured element is parsed. This data is ignored.

Parameters:
  • buffer – The buffer to read data from
  • offset – The offset in the buffer where to start reading
  • length – The amount of data we are allowed to read from the buffer
Returns:

The number of bytes used from the buffer

save() → Union[source]

Save the internal state of this object as a buffer.

Returns:The buffer with the data from this element