dhcpcanon Python API Reference

dhcpcanon.dhcpcapfsm

DCHP client implementation of the Anonymity Profiles [RFC 7844].

dhcpcanon.dhcpcap

Client class for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.dhcpcaplease

Lease class for the DHCP client implementation of the Anonymity Profile ([RFC 7844])..

dhcpcanon.clientscript

Class to Initialize and call external script.

dhcpcanon.timers

Timers for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.dhcpcaputils

Util functions for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.constants

Constants for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.conflog

Logging configuration.

dhcpcapfsm module

DCHP client implementation of the Anonymity Profiles [RFC 7844].

class dhcpcanon.dhcpcapfsm.DHCPCAPFSM(self, debug=0, store=1, **kargs)[source]

DHCP client Finite State Machine (FSM).

BOUND(*args: ATMT, **kargs: Any) NewStateRequested
END(*args: ATMT, **kargs: Any) NewStateRequested
ERROR(*args: ATMT, **kargs: Any) NewStateRequested
INIT(*args: ATMT, **kargs: Any) NewStateRequested
REBINDING(*args: ATMT, **kargs: Any) NewStateRequested
RENEWING(*args: ATMT, **kargs: Any) NewStateRequested
REQUESTING(*args: ATMT, **kargs: Any) NewStateRequested
SELECTING(*args: ATMT, **kargs: Any) NewStateRequested
action_transmit_discover()[source]

Action on timeout, send DISCOVER.

action_transmit_request()[source]

Action on X: send REQUEST.

actions: Dict[str, List[_StateWrapper]] = {'lease_expires': [], 'rebinding_time_expires': [<function DHCPCAPFSM.action_transmit_request>], 'receive_ack_rebinding': [<function DHCPCAPFSM.on_ack_requesting>], 'receive_ack_renewing': [<function DHCPCAPFSM.on_renewing>], 'receive_ack_requesting': [<function DHCPCAPFSM.on_ack_requesting>], 'receive_nak_rebinding': [], 'receive_nak_renewing': [], 'receive_nak_requesting': [], 'receive_offer': [<function DHCPCAPFSM.action_transmit_request>], 'renewing_time_expires': [<function DHCPCAPFSM.action_transmit_request>], 'timeout_delay_before_selecting': [<function DHCPCAPFSM.action_transmit_discover>], 'timeout_request_rebinding': [<function DHCPCAPFSM.action_transmit_request>], 'timeout_request_renewing': [<function DHCPCAPFSM.action_transmit_request>], 'timeout_requesting': [<function DHCPCAPFSM.action_transmit_request>], 'timeout_selecting': [<function DHCPCAPFSM.action_transmit_discover>]}
conditions: Dict[str, List[_StateWrapper]] = {'BOUND': [], 'END': [], 'ERROR': [], 'INIT': [], 'REBINDING': [], 'RENEWING': [], 'REQUESTING': [], 'SELECTING': []}
dict_self()[source]

Return the self object attributes not inherited as dict.

get_timeout(state, function)[source]

Workaround to get timeout in the ATMT.timeout class method.

initial_states: List[_StateWrapper] = [<function ATMT.state.<locals>.deco.<locals>._state_wrapper>]
ioevents: Dict[str, List[_StateWrapper]] = {'BOUND': [], 'END': [], 'ERROR': [], 'INIT': [], 'REBINDING': [], 'RENEWING': [], 'REQUESTING': [], 'SELECTING': []}
ionames: List[str] = []
iosupersockets: List[SuperSocket] = []
lease_expires()[source]

Timeout lease time, transition to INIT.

Not sending DHCPRELEASE to minimize deanonymization

[RFC 2131#section-4.4.6]:

Note that the correct operation
of DHCP does not depend on the transmission of DHCPRELEASE.
on_ack_requesting()[source]

Action on receive ACK requesting in REQUESTING state: set timers.

on_renewing()[source]

Action on renewing on RENEWING state.

Not recording lease, but restarting timers.

process_received_ack(pkt)[source]

Process a received ACK packet.

Not specifiyed in [RFC 7844]. Probe the offered IP in [RFC 2131#section-2.2.]:

the allocating
server SHOULD probe the reused address before allocating the
address, e.g., with an ICMP echo request, and the client SHOULD
probe the newly received address, e.g., with ARP.

The client SHOULD broadcast an ARP
reply to announce the client's new IP address and clear any
outdated ARP cache entries in hosts on the client's subnet.

It is also not specifiyed in [RFC 7844] nor [RFC 2131] how to check that the offered IP is valid.

Todo

  • Check that nor dhclient nor systemd-networkd send an ARP.

  • Check how other implementations check that the ACK paremeters are valid, ie, if the ACK fields match the fields in the OFFER.

  • Check to which state the client should go back to when the offered parameters are not valid.

process_received_nak(pkt)[source]

Process a received NAK packet.

rebinding_time_expires()[source]

Timeout rebinding time (T2), transition to REBINDING.

receive_ack_rebinding(pkt)[source]

Receive ACK in REBINDING state.

receive_ack_renewing(pkt)[source]

Receive ACK in RENEWING state.

receive_ack_requesting(pkt)[source]

Receive ACK in REQUESTING state.

receive_nak_rebinding(pkt)[source]

Receive NAK in REBINDING state.

receive_nak_renewing(pkt)[source]

Receive NAK in RENEWING state.

receive_nak_requesting(pkt)[source]

Receive NAK in REQUESTING state.

receive_offer(pkt)[source]

Receive offer on SELECTING state.

recv_conditions: Dict[str, List[_StateWrapper]] = {'BOUND': [], 'END': [], 'ERROR': [], 'INIT': [], 'REBINDING': [<function DHCPCAPFSM.receive_ack_rebinding>, <function DHCPCAPFSM.receive_nak_rebinding>], 'RENEWING': [<function DHCPCAPFSM.receive_ack_renewing>, <function DHCPCAPFSM.receive_nak_renewing>], 'REQUESTING': [<function DHCPCAPFSM.receive_ack_requesting>, <function DHCPCAPFSM.receive_nak_requesting>], 'SELECTING': [<function DHCPCAPFSM.receive_offer>]}
renewing_time_expires()[source]

Timeout renewing time (T1), transition to RENEWING.

reset(iface=None, client_mac=None, xid=None, scriptfile=None)[source]

Reset object attributes when state is INIT.

select_offer()[source]

Select an offer from the offers received.

[RFC 2131#section-4.2]:

DHCP clients are free to use any strategy in selecting a DHCP
server among those from which the client receives a DHCPOFFER.

[RFC 2131#section-4.4.1]:

The time
over which the client collects messages and the mechanism used to
select one DHCPOFFER are implementation dependent.

Nor [RFC 7844] nor [RFC 2131] specify the algorithm. Here, currently the first offer is selected.

Todo

  • Check other implementations algorithm to select offer.

send_discover()[source]

Send discover.

send_request()[source]

Send request.

[RFC 2131#section-3.1]:

a client retransmitting as described in section 4.1 might retransmit the DHCPREQUEST message four times, for a total delay of 60 seconds

Todo

  • The maximum number of retransmitted REQUESTs is per state or in total?

  • Are the retransmitted REQUESTs independent to the retransmitted DISCOVERs?

set_timeout(state, function, newtimeout)[source]

Workaround to change timeout values in the ATMT.timeout class method.

self.timeout format is:

{'STATE': [
    (TIMEOUT0, <function foo>),
    (TIMEOUT1, <function bar>)),
    (None, None)
    ],
}
set_timers()[source]

Set renewal, rebinding times.

states: Dict[str, _StateWrapper] = {'BOUND': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'END': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'ERROR': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'INIT': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'REBINDING': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'RENEWING': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'REQUESTING': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>, 'SELECTING': <function ATMT.state.<locals>.deco.<locals>._state_wrapper>}
stop_states: List[_StateWrapper] = []
timeout: Dict[str, _TimerList] = {'BOUND': [<Timer 0.000000(604800.000000)>], 'END': [], 'ERROR': [], 'INIT': [<Timer 0.000000(10.000000)>], 'REBINDING': [<Timer 0.000000(75600.000000)>, <Timer 0.000000(1209600.000000)>], 'RENEWING': [<Timer 0.000000(226800.000000)>, <Timer 0.000000(1058400.000000)>], 'REQUESTING': [<Timer 0.000000(60.000000)>], 'SELECTING': [<Timer 0.000000(60.000000)>]}
timeout_delay_before_selecting()[source]

Timeout delay selecting in INIT state.

timeout_request_rebinding()[source]

Timeout of request rebinding on REBINDING state.

Same comments as in dhcpcapfsm.DHCPCAPFSM.timeout_requesting().

timeout_request_renewing()[source]

Timeout of renewing on RENEWING state.

Same comments as in dhcpcapfsm.DHCPCAPFSM.timeout_requesting().

timeout_requesting()[source]

Timeout requesting in REQUESTING state.

Not specifiyed in [RFC 7844]

[RFC 2131#section-3.1]:

might retransmit the
DHCPREQUEST message four times, for a total delay of 60 seconds
timeout_selecting()[source]

Timeout of selecting on SELECTING state.

Not specifiyed in [RFC 7844]. See comments in dhcpcapfsm.DHCPCAPFSM.timeout_request().

dhcpcap module

Client class for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

class dhcpcanon.dhcpcap.DHCPCAP(iface=None, client_mac=None, client_ip='0.0.0.0', client_port=68, server_mac='ff:ff:ff:ff:ff:ff', server_ip='255.255.255.255', server_port=67, lease=NOTHING, event=None, prl=None, xid=None)[source]

.

gen_bootp()[source]

Generates BOOTP layer part of DHCP packet.

[ RFC 7844#section-3.4 ]

The presence of this address is necessary for the proper operation
of the DHCP service.

[RFC 7844#section-3.]

MAY contain the Client Identifier option,
gen_bootp_unicast()[source]

Generates BOOTP layer part of unicast DHCP packet.

Same comments as in gen_bootp

gen_check_lease_attrs(attrs_dict)[source]

Generate network mask in CIDR format and subnet.

Validate the given arguments. Otherwise AddrFormatError exception will be raised and catched in the FSM.

gen_decline()[source]

Generate DHCP decline packet (broadcast).

[RFC 7844#section-3.]

MUST contain the Message Type option,
MUST contain the Server Identifier option,
MUST contain the Requested IP address option;

Note

currently not being used.

gen_discover()[source]

Generate DHCP DISCOVER packet.

[RFC 7844#section-3.1]

SHOULD randomize the ordering of options

If this can not be implemented
MAY order the options by option code number (lowest to highest).

[RFC 7844#section-3.]

MAY contain the Parameter Request List option.
gen_ether_ip()[source]

Generates link layer and IP layer part of DHCP packet.

For broadcast packets is:

Ether(src=client_mac, dst=”ff:ff:ff:ff:ff:ff”) / IP(src=”0.0.0.0”, dst=”255.255.255.255”) /

gen_ether_ip_unicast()[source]

Generates link layer and IP layer part of DHCP packet.

For unicast packets is:

Ether(src=client_mac, dst=server_mac) / IP(src=client_ip?, dst=server_ip) /

gen_inform()[source]

Generate DHCP inform packet (unicast).

[RFC 7844#section-3.]

MUST contain the Message Type option,

Note

currently not being used.

gen_release()[source]

Generate DHCP release packet (broadcast?).

[RFC 7844#section-3.]

MUST contain the Message Type option and
MUST contain the Server Identifier option,

Note

currently not being used.

gen_request()[source]

Generate DHCP REQUEST packet.

[RFC 7844#section-3.1]

SHOULD randomize the ordering of options

If this can not be implemented
MAY order the options by option code number (lowest to highest).

[RFC 7844#section-3.]

MAY contain the Parameter Request List option.

If in response to a DHCPOFFER,:

MUST contain the corresponding Server Identifier option
MUST contain the Requested IP address option.

If the message is not in response to a DHCPOFFER (BOUND, RENEW),::
MAY contain a Requested IP address option
gen_request_unicast()[source]

Generate DHCP REQUEST unicast packet.

Same comments as in gen_request apply.

gen_udp()[source]

Generates UDP layer part of DHCP packet.

UDP layer is always:

UDP(sport=68, dport=67) /

handle_ack(pkt, time_sent_request)[source]

.

handle_offer(pkt)[source]

.

handle_offer_ack(pkt, time_sent_request=None)[source]

Create a lease object with the values in OFFER/ACK packet.

dhcpcaplease module

Lease class for the DHCP client implementation of the Anonymity Profile ([RFC 7844])..

class dhcpcanon.dhcpcaplease.DHCPCAPLease(address='', server_id='', next_server='', router='', subnet_mask='', broadcast_address='', domain='', name_server='', subnet='', lease_time='', renewal_time='', rebinding_time='', interface='', subnet_mask_cidr='', network='', expiry='', renew='', rebind='')[source]

.

info_lease()[source]

Print lease information.

set_times(sent_dt)[source]

Set timers for the lease given the time in which the request was sent.

[RFC 2131#section-4.4.1]:

The client records the lease expiration time
as the sum of the time at which the original request was
sent and the duration of the lease from the DHCPACK message.

clientscript module

Class to Initialize and call external script.

class dhcpcanon.clientscript.ClientScript(scriptname=None, env=NOTHING)[source]

Simulates the behaviour of the isc-dhcp client-script or nm-dhcp-helper.

client-script or nm-dhcp-helper.

script_go(scriptname=None, env=None)[source]

Run the external script.

script_init(lease, state, prefix='', medium='')[source]

Initialize environment to pass to the external script.

timers module

Timers for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.timers.future_dt_str(dt, td)[source]

.

dhcpcanon.timers.gen_delay_selecting()[source]

Generate the delay in seconds in which the DISCOVER will be sent.

[RFC 2131#section-4.4.1]:

The client SHOULD wait a random time between one and ten seconds to
desynchronize the use of DHCP at startup.
dhcpcanon.timers.gen_rebinding_time(lease_time, elapsed=0)[source]

.

dhcpcanon.timers.gen_renewing_time(lease_time, elapsed=0)[source]

Generate RENEWING time.

[RFC 2131#section-4.4.5]:

T1
defaults to (0.5 * duration_of_lease).  T2 defaults to (0.875 *
duration_of_lease).  Times T1 and T2 SHOULD be chosen with some
random "fuzz" around a fixed value, to avoid synchronization of
client reacquisition.
dhcpcanon.timers.gen_timeout_request_rebind(lease)[source]

.

dhcpcanon.timers.gen_timeout_request_renew(lease)[source]

Generate time in seconds to retransmit DHCPREQUEST.

[RFC 2131#section-4..4.5]:

In both RENEWING and REBINDING states,
if the client receives no response to its DHCPREQUEST
message, the client SHOULD wait one-half of the remaining
time until T2 (in RENEWING state) and one-half of the
remaining lease time (in REBINDING state), down to a
minimum of 60 seconds, before retransmitting the
DHCPREQUEST message.
dhcpcanon.timers.gen_timeout_resend(attempts)[source]

Generate the time in seconds in which DHCPDISCOVER wil be retransmited.

[RFC 2131#section-3.1]:

might retransmit the
DHCPREQUEST message four times, for a total delay of 60 seconds

[RFC 2131#section-4.1]:

For example, in a 10Mb/sec Ethernet
internetwork, the delay before the first retransmission SHOULD be 4
seconds randomized by the value of a uniform random number chosen
from the range -1 to +1.  Clients with clocks that provide resolution
granularity of less than one second may choose a non-integer
randomization value.  The delay before the next retransmission SHOULD
be 8 seconds randomized by the value of a uniform number chosen from
the range -1 to +1.  The retransmission delay SHOULD be doubled with
subsequent retransmissions up to a maximum of 64 seconds.
dhcpcanon.timers.nowutc()[source]

.

dhcpcaputils module

Util functions for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.dhcpcaputils.detect_initial_network()[source]
dhcpcanon.dhcpcaputils.detect_speed_network()[source]
dhcpcanon.dhcpcaputils.discover_ifaces()[source]
dhcpcanon.dhcpcaputils.gen_xid()[source]
dhcpcanon.dhcpcaputils.isack(packet)[source]

.

dhcpcanon.dhcpcaputils.isnak(packet)[source]

.

dhcpcanon.dhcpcaputils.isoffer(packet)[source]

.

constants module

Constants for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).

dhcpcanon.constants.PRL = b'\x01\x03\x06\x0f\x1f!+,./y\xf9\xfc'

SD_DHCP_OPTION_SUBNET_MASK = 1 SD_DHCP_OPTION_ROUTER = 3 SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6 SD_DHCP_OPTION_DOMAIN_NAME = 15 SD_DHCP_OPTION_ROUTER_DISCOVER = 31 SD_DHCP_OPTION_STATIC_ROUTE = 33 SD_DHCP_OPTION_VENDOR_SPECIFIC = 43 SD_DHCP_OPTION_NETBIOS_NAMESERVER = 44 SD_DHCP_OPTION_NETBIOS_NODETYPE = 46 SD_DHCP_OPTION_NETBIOS_SCOPE = 47 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252

conflog module

Logging configuration.