DHCPv4

The system provides a Python object alc.dhcpv4 to inspect and modify DHCPv4 packets.

The alc.dhcpv4 object

Attributes

The object exposes the header fields as attributes on the object.

Attribute

Field

Access

Type

pkt_len

total length, in bytes, of the original DHCPv4-layer, pad-options included

ro

int

pkt_netlen

total length, in bytes, of the original DHCPv4-layer, pad-options excluded

ro

int

op

op

ro

bytes

htype

htype

rw

bytes

hlen

hlen

rw

bytes

hops

hops

rw

bytes

xid

xid

ro

bytes

secs

secs

rw

bytes

flags

flags

rw

bytes

ciaddr

ciaddr

rw

bytes

yiaddr

yiaddr

rw

bytes

siaddr

siaddr

rw

bytes

giaddr

giaddr

rw

bytes

chaddr

chaddr

rw

bytes

sname

sname

rw

bytes

file

file

rw

bytes

Methods

alc.Dhcpv4.drop()

Drops the resulting packet.

alc.Dhcpv4.pad(min_size=300, /)

Pads the resulting DHCPv4 packet to the specified min_size with pad option(0) after executing the whole script. Padding is not performed if the result packet is already >=min_size. The default value of min_size is 300.

Although not defined in the DHCPv4 RFC, many DHCPv4 implementations require a minimum length of 300 bytes. This method can pad the result packet to the specified min_size.

Parameters

min_size (int) – minimal size of resulting packet

alc.Dhcpv4.get(option_code, /)

Returns all values of options with the specified option-code. The values are returned as the exact bytestrings as they appear in the packet.

  • If the specified option does not exist, the result is an empty tuple: ()

  • If a specific instance has zero length or no values, the corresponding bytestring in the result tuple is an empty bytestring: b””

param int option_code

option-code to fetch

rtype

tuple of bytestrings

import alc
# For a packet with an address lease time option(51) with value 60:
print(alc.dhcpv4.get(51))
# (b‘\x00\x00\x00\x3c’,)
print([int.from_bytes(option, 'big') for option in alc.dhcpv4.get(51)])
# [60]
alc.Dhcpv4.set(option_code, value, /)

Deletes existing options of the specified code and inserts new options with the specified code and value. Multiple values can be specified in a tuple, in which case an option is added for each item in the tuple.

param int option_code

option-code to set

param bytes|tuple(bytes) value

value of the option; the length is computed from this value

# To insert an address lease time option(51) with value 60:
alc.dhcpv4.set(51, b'\x00\x00\x00\x3c')
alc.Dhcpv4.clear(option_code, /)

Removes all options with the specified option-code.

Parameters

option_code (int) – option-code to clear

alc.Dhcpv4.getOptionList()

Returns a tuple of option-codes that are present in the top-level packet.

  • The order of the elements is the same as they appear in the packet.

  • If there are multiple instances of the same option, the option-code also appears multiple times in the tuple.

  • Pad(0) and End(255) options are excluded.

# for a discovery packet with options
# msg-type/lease-time/request-addr/parameter-request-list/agent-info/end:
print(alc.dhcpv4.getOptionList())
# (53,51,50,55,82,255)
alc.Dhcpv4.get_relayagent()

Retrieves the relay-agent(82) option as a D4OL data structure.

alc.Dhcpv4.set_relayagent(value, /)

Sets the relay-agent(82) option as a D4OL data structure.

param value

relay-agent(82) value to set

type value

D4OL

alc.Dhcpv4.get_vendorspecific()

Retrieves the vendor-specific(43) option as a D4OL data structure.

alc.Dhcpv4.set_vendorspecific(value, /)

Sets the vendor-specific(43) option as a D4OL data structure.

Parameters

value (D4OL) – vendor-specific(43) value to set

DHCPv4 Option List (D4OL)

The D4OL is a nested data structure which represents the value of some DHCPv4 options.

  • The D4OL is a list where each element in the list is an instance of the specific option.

  • Each element is a dictionary, where:

    • the key is the sub-option-code (integer)

    • the value is a list with all instances of the sub-option, and each item in the list is a bytestring corresponding to the sub-option-value.

Example: for a packet with an option82 as in the following:

Option: (82) Agent Information Option
    Length: 22
    Option (82) Suboption: (1) Agent Circuit ID
        Length: 8
        Agent Circuit ID: 4a616e737656e73
    Option (82) Suboption: (2) Agent Remote ID
        Length: 10
        Agent Remote ID: 62617369632364617461

results in the following D4OL:

option82 = alc.dhcpv4.get_relayagent() # [{2: [b'basic#data'], 1: [b'Jan:73sens']}]
option82[0][2][0] = b'basic#video' # [{2: [b'basic#video'], 1: [b'Jan:73sens']}]
alc.dhcpv4.set_relayagent(option82)