DHCP client disclosing less identifying information.
Python implementation of the DHCP Anonymity Profiles RFC 7844 designed for users that wish to remain anonymous to the visited network minimizing disclosure of identifying information.
This implementation uses the Python Scapy Automata
As the [RFC 7844] stats:
Some DHCP options carry unique identifiers. These identifiers can enable device tracking even if the device administrator takes care of randomizing other potential identifications like link-layer addresses or IPv6 addresses. The anonymity profiles are designed for clients that wish to remain anonymous to the visited network. The profiles provide guidelines on the composition of DHCP or DHCPv6 messages, designed to minimize disclosure of identifying information.
If you wish to signal a bug or report a feature request, please fill-in an issue on the dhcpcanon issue tracker.
RFC7844 DHCPv4 restricted version summary, questions and dhcpcanon specification
Summary of questions regarding the RFCs and the implementations
Message types and options details in all layers
Installation and running cases
Minimising dhcpcanon privileges
dhcpcanon integration with network managers
dhcpcanon Python API Reference
Recommended documentation not included in this repository:
Related RFCs
RFC7844 comments and summary
dhcpcanon is copyright 2016, 2017 by juga <juga at riseup dot net>, and is licensed under the terms of the MIT license.
To all the persons that have given suggestions and comments about this implementation, the authors of the RFC 7844, the Prototype Fund Project of the Open Knowledge Foundation Germany and the Federal Ministry of Education and Research for funding partially this project.
The recommended way to install dhcpcanon
is with your package source
distribution, as it will also install other system files.
Currently is availabe for Debian unstable/testing. It can be installed with a package manager or in command line:
sudo apt install dhcpcanon
The main script will be installed in /sbin/dhcpcanon
, a systemd service
will be enabled and run by default, so there is no need to run anything manually.
Important: when running dhcpcanon
the hardware address
(MAC) should be randomized.
You can use macchanger,
macouflage or other.
In case you would like to have a newer version or it is not packaged for your distribution, you can install it from the source code.
Install system dependencies, in Debian/Ubuntu:
sudo apt install python3-dev
Obtain the source code:
git clone https://github.com/juga0/dhcpcanon/
Install dhcpcanon
and system files:
sudo ./install.sh
Follow the two first steps in the previous paragraph.
To install dhcpcanon
and the systemd
service:
sudo make install WITH_SYSTEMD=true
In Debian this will install all the required files under /usr/local
.
WITH_SYSTEMD
will install a systemd service and enable it, to run it:
systemctl start dhcpcanon
It’s possible to also install support for udev:
sudo apt install sudo make install WITH_SYSTEMD=true
sudo make install WITH_SYSTEMD=true WITH_SYSTEMD_UDEV=true
And apparmor profile:
sudo apt install apparmor
sudo make install WITH_APPARMOR=true
In the case that you would like to install without root privileges, you can install it without the systemd service and you can specify an alternative location, for instance:
make --prefix=/home/user/.local install
Note however that without systemd dhcpcanon
will need to be run with root
privileges, while the systemd service drop dhcpcanon
root privileges and
only keeps the required network capabilities.
You would also need to install
resolvconf-admin
to be able to run it as non root user and set up DNS servers provided by the DHCP server.
It will be possible to set up DNS servers with systemd
too soon.
An alternative to do not run dhcpcanon
with root privileges nor systemd,
is to use ambient-rs wrapper
and run:
RUST_BACKTRACE=1 ./target/debug/ambient \
-c NET_RAW,NET_ADMIN,NET_BIND_SERVICE \
/usr/bin/python3 -m dhcpcanon.dhcpcanon -v
The pip package does not install either system files and it can be installed without root, but it still needs to be run as root, as commented in the last section.:
pip3 install dhcpcanon
In Debian this will install the files in /home/youruser/.local
Note also that if you install it in a virtualenv, when executing dhcpcanon
with sudo
, won’t use the virtualenv. To keep the virtualenv run it with:
sudo /pathtovirtualenv/bin/dhcpcanon
It is recommended to install dhcpcanon
in a python virtual environment.
Check https://virtualenv.pypa.io/en/latest/installation.html. In Debian:
sudo apt install python3-virtualenv
Create a virtual environment:
mkdir ~/.virtualenvs
virtualenv ~/.virtualenvs/dhcpcanonenv -p /usr/bin/python3
source ~/.virtualenvs/dhcpcanonenv/bin/activate
Install it:
pip3 install -e .
You can download this project in either zip or tar formats.
If dhcpcanon
has be installed with systemd, it can be started with:
sudo systemctl start dhcpcanon
After installing, it can also be run manually:
sudo dhcpcanon
There is no need to pass any argument, most of the arguments are only used when
dhcpcanon
is called by other program (systemd
or
gnome network manager
) and mimic the dhclient
arguments.
You can specify which network interface to use passing it as an argument. Without specificying the network interface, it will use the active interface.
An useful argument when reporting bugs is -v
.
An updated command line usage description can be obtained with:
dhcpcanon -h
sbin/dhcpcanon-script systemd/dhcpcanon.service tmpfiles.d/dhcpcanon.conf systemd/network/90-dhcpcanon.link console_scripts -> /sbin/dhcpcanon
[X] create debian package
[X] create documentation
[X] calculate retransmission times for DISCOVER
[X] create tests
[ ] (WIP) integrate with Network Manager
[ ] listen in several interfaces
[X] create systemd service
[X] create init.d daemon: Won’t fix.
[X] limit privileges
[X] include MAC anonymization module: Debian package suggest it.
[X] create apparmor profile
[ ] implement IPv6
dhcpcanon
¶We welcome contributions of any kind (ideas, code, tests, documentation, examples, …).
flake8
script - e.g. flake8 dhcpcanon/edited_file.py
or
tox -e style
.
Second command will run flake8 on all the files in the repository.And most importantly, follow the existing style in the file you are editing and be consistent.
For documenting the API we we use Sphinx and reStructuredText syntax.
Go to our issue tracker and open a new issue for your changes there.
Fork our Github git repository. Your fork will be used to hold your changes.
Commit often and rebase master
Make sure that all the code you have added or modified has appropriate test
coverage. Also make sure all the tests including the existing ones still pass
using tox
tox
You can then push your feature branch to your remote and open a pull request.
Please do not report security issues using the public Issue tracker. Send a description of it to juga at riseup dot net. You are also encouraged to encrypt this email using GPG. The key can be found in the public servers.
This docummentation is partly copied from libcloud contributing
on DHCP clients, network managers and libraries in Debian/Ubuntu
man 5 systemd.network
=> DHCP options
Can use 3 DHCP clients: - ISC DHCP client: package isc-dhpc-client, binarry dhclient - systemd DHCP client - built-in DHCP client
is an all-Python, RFC 2131-compliant DHCP server, with support for most common DHCP extensions and extensive site-specific customisation.
GPL. Last updated 12/03/2017. Commiters: +3
dhcpcanon
specification¶This document is a more restrictive version summary of [RFC 7844],
where the keywords (key words
[RFC 2119]) commented in
RFC7844 comments
are actually replaced. Use diff
to see specific differences between these
two documents.
See Summary of questions regarding the RFCs and the implementations for a summary of the questions stated here.
Note
Note
See Message types and options details in all layers for a summary of the messages implementation
SHOULD randomize the ordering of options
If this can not be implemented MUST order the options by option code number (lowest to highest).
MUST contain the Message Type option,
MUST NOT contain the Client Identifier option, MUST NOT contain the Parameter Request List option. MUST NOT contain any other option.
MUST contain the Message Type option,
MUST NOT contain the Client Identifier option, MUST NOT contain the Parameter Request List option. MUST NOT contain any other 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),:
MUST NOT contain a Requested IP address option
MUST contain the Message Type option,
MUST contain the Server Identifier option,
MUST contain the Requested IP address option;
MUST NOT contain the Client Identifier option.
To do not leak when the client leaves the network, this message type MUST NOT be implemented.
In this case, servers might run out of leases, but that is something that servers should fix decreasing the lease time.
MUST contain the Message Type option,
MUST NOT contain the Client Identifier option, MUST NOT contain the Parameter Request List option. It MUST NOT contain any other option.
MUST NOT include in the message a Client IP address that has been obtained
with a different link-layer address.
MUST NOT use the Requested IP address option in DHCPDISCOVER messages.
MUST use the option when mandated (DHCPREQUEST)
If in INIT-REBOOT:
MUST perform a complete four-way handshake, starting with a DHCPDISCOVER
This is like not having INIT-REBOOT state?:
If the client can ascertain that this is exactly the same network to which it was previously connected, and if the link-layer address did not change,
MAY issue a DHCPREQUEST to try to reclaim the current address.
This is like INIT-REBOOT state?
Is there a way to know if
the link-layer address changed without leaking the link-layer?
If the hardware address is reset to a new randomized value,
the DHCP client MUST use the new randomized value in the DHCP messages
The client should be restarted when the hardware address changes and use the current address instead of the permanent one.
MUST NOT have this option
In the case that it would have this option because otherwise the server does not answer to the requests,:
DHCP
clients MUST use client identifiers based solely on the link-layer
address that will be used in the underlying connection.
Nodes visiting untrusted networks MUST NOT send or use the PXE options.
MUST NOT use the
Vendor-Specific Information option (code 43), the Vendor Class
Identifier option (code 60), the V-I Vendor Class option (code 124),
or the V-I Vendor-Specific Information option (code 125),
Implementers SHOULD provide a way for clients to control when the
anonymity profiles are used and when standard behavior is preferred.
dhcpcanon
does not currently implement the standard behavior described in
[RFC 2131] in order to keep the implementation simple and
because all existing implementations already implement it
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 perform a
check on the suggested address to ensure that the address is not
already in use. For example, if the client is on a network that
supports ARP, the client may issue an ARP request for the suggested
request. When broadcasting an ARP request for the suggested address,
the client must fill in its own hardware address as the sender's
hardware address, and 0 as the sender's IP address, to avoid
confusing ARP caches in other hosts on the same subnet.>>
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.
Currently, there is not any probe
Sending DHCPDISCOVER [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.
a client retransmitting as described in section 4.1 might retransmit the
DHCPREQUEST message four times, for a total delay of 60 seconds
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.
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.
DHCP clients are free to use any strategy in selecting a DHCP server
among those from which the client receives a DHCPOFFER message.
client may choose to collect several DHCPOFFER
messages and select the "best" offer.
If the client receives no acceptable offers, the client
may choose to try another DHCPDISCOVER message.
The client collects DHCPOFFER messages over a period of time, selects
one DHCPOFFER message from the (possibly many) incoming DHCPOFFER
messages
The time
over which the client collects messages and the mechanism used to
select one DHCPOFFER are implementation dependent.
Currently, the first OFFER is chosen
Times T1 and T2 are configurable by the server through options. 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.
T1 is then calculated as:
renewing_time = lease_time * 0.5 - time_elapsed_after_request
range_fuzz = lease_time * 0.875 - renewing_time
renewing_time += random.uniform(-(range_fuzz), +(range_fuzz))
And T2:
rebinding_time = lease_time * 0.875 - time_elapsed_after_request
range_fuzz = lease_time - rebinding_time
rebinding_time += random.uniform(-(range_fuzz), +(range_fuzz))
The range_fuzz is calculated in the same way that systemd
implementation
does
There are scenarios in which a client connecting to a network
remembers a previously allocated address, i.e., when it is in the
INIT-REBOOT state. In that state, any client that is concerned with
privacy SHOULD perform a complete four-way handshake, starting with a
DHCPDISCOVER, to obtain a new address lease. If the client can
ascertain that this is exactly the same network to which it was
previously connected, and if the link-layer address did not change,
the client MAY issue a DHCPREQUEST to try to reclaim the current
address.
For the sake of simplicity and privacy dhcpcanon
does not currently
implement the INIT-REBOOT state nor reuse previously allocated addresses.
In future stages of dhcpcanon
would be possible to reuse a previously
allocated address.
In order to do not leak identifying information when doing so,
it would be needed:
It is possible also that dhcpcanon
will include a MAC randomization module
in the same distribution package or would require it in order to start.
This is a summary of the questions stated in RFC7844 DHCPv4 restricted version summary
if
the link-layer address changed without leaking the link-layer?Sending DHCPDISCOVER [RFC 2131#section-4.4.1]
[RFC 2131#section-3.1], [RFC 2131#section-4.4.5], [RFC 2131#section-4.1]
Always broadcast in AP:
Ehter: src=client_mac, dst="ff:ff:ff:ff:ff:ff"
IP: src="0.0.0.0", dst="255.255.255.255"
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
DHCP: Message Type option (message-type in scapy)
In SELECTING state: Broadcast in AP:
Ehter: src=client_mac, dst="ff:ff:ff:ff:ff:ff"
IP: src="0.0.0.0", dst="255.255.255.255"
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
DHCP: Message Type option (message-type in scapy)
DHCP: Server Identifier option (server_id in scapy, siaddr in server BOOTP offer)
DHCP: Requested IP option (requested_addr in scapy, yiaddr in server BOOTP offer)
In RENEWING state: Unicast to server id:
Ehter: src=client_mac, dst=server_mac
IP: src=client_ip, dst=server_ip
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
DHCP: Message Type option (message-type in scapy)
Client IP address (ciaddr=client_ip)?
In REBINDING state: broadcast:
Ehter: src=client_mac, dst="ff:ff:ff:ff:ff:ff"
IP: src="0.0.0.0", dst="255.255.255.255"
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
DHCP: Message Type option (message-type in scapy)
Client IP address (ciaddr=client_ip)?
Always broadcast?:
Ehter: src=client_mac, dst="ff:ff:ff:ff:ff:ff"
IP: src="0.0.0.0", dst="255.255.255.255"
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
DHCP: Message Type option (message-type in scapy)
DHCP: Server Identifier option (server_id in scapy, siaddr in server BOOTP offer)
DHCP: Requested IP option (requested_addr in scapy, yiaddr in server BOOTP offer)
Always unicast, is not being used:
Ehter: src=client_mac, dst=server_mac
IP: src=client_ip, dst=server_ip
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
DHCP: Message Type option (message-type in scapy)
DHCP: Server Identifier option (server_id in scapy, siaddr in server BOOTP offer)
Always broadcast in Anonymity Profile, is not being used:
Ehter: src=client_mac, dst="ff:ff:ff:ff:ff:ff"
IP: src=client_ip, dst="255.255.255.255"
UDP: sport=68, dport=67
BOOTP: Client Hardware address (chaddr in scapy)
BOOTP: Client IP address (ciaddr=client_ip)
DHCP: Message Type option (message-type in scapy)
dhcpcanon
privileges¶Reasons why a DHCP client needs to run with root privileges:
open sockets in privilege ports (68)
open RAW sockets: to receive packets without having an IP set yet
to set the IP offered
Note
dhcpcanon
does not need privileges to set up the IP, as that is done
by a separated script, as dhclient
does.
Possible solutions to minimise privileges and their associated problems:
problem: if the client stays connected until the renewing/rebinding time, privileges would be needed again and dropping privileges temporally it is not recommended [].
possible solutions: do not implement RENEWING/REBINDING states.
problem: this would not be compliant with RFC 2131 nor 7844.
pro: in “usual” networks, if the client stays enough time connected to the network, the lease would expire it could just restart in the INIT state.
Todo
which would be the associated problems to this solution?
- problem: same as 1.
Note
it’s not possible to set net capabilities directly to a python script, they would need to be set to the python binary, but that would give the capabilities to any python script. Python binary could also be copied, set the capabilies, and that script call the client, but would have the same problem as giving the capabilities to the original python binary
dhcpcanon
could call a binary with privileges to create the sockets
every time it needs to do so.
It’s needed to change several parts of the current implementation.
to have the process be granted just the capabilities it needs, by the system-level process manager.
This is already implemented with systemd
wrapper that does the same as in 4. without a system-level process manager. See section “wrapper to inherit capabilities”
It could be solved with infinity0’s wrapper <https://github.com/infinity0/ambient-rs> running:
RUST_BACKTRACE=1 ./target/debug/ambient -c NET_RAW,NET_ADMIN,NET_BIND_SERVICE /usr/bin/python3 -m dhcpcanon.dhcpcanon -v
wrapper with privileges to disable linux Remote Path (RP) filter, open sockets, then call the client:
- problems:
- it still needs root to change the default RP settings
- it would only allow that the DHCP offers are received from other interfaces [], but still RAW sockets are needed to receive packets in the same interface that does not have an IP address yet
- same as 1.
With capsh
, dhcpcanon
could be launched as another user and
inherit only the required capabilities, in a similar way as
systemd.service
does:
capsh --caps=cap_net_raw,cap_net_bind_service,cap_net_admin+epi --keep=1 -- -c "mkdir -p /run/dhcpcanon && cd /run/dhcpcanon && su -c 'exec /sbin/dhcpcanon enp0s25' -s /bin/sh dhcpcanon"
-s
is needed cause dhcpcanon shell is /bin/false
However this does not have capabilities to create the socket.
To show the capabilities that are actually inherited:
capsh --keep=1 --secbits=0x1C --caps=cap_net_raw,cap_net_bind_service,cap_net_admin+epi -- -c "mkdir -p /run/dhcpcanon && cd /run/dhcpcanon && su -c '/sbin/capsh --print' -s /bin/sh dhcpcanon"
In man capsh
--securebits
is not documented, securebits.h
has some documentation, but it seems to be needed a newer version of
libcap
as commented in this post
dhcpcanon
integration with network managers¶Network Manager
¶Gnome Network Manager has several components.
In Debian the service NetworkManager
by default
calls dhclient
which in turn calls nm-dhcp-helper
.
Depending on the configuration, dhclient is called with the parameters:
/sbin/dhclient -d -q
-sf /usr/lib/NetworkManager/nm-dhcp-helper
-pf /var/run/dhclient-<interface>.pid
-lf /var/lib/NetworkManager/dhclient-<?>-<interface>.lease
-cf /var/lib/NetworkManager/dhclient-<interface>.conf
<interface>
Dclient calls nm-dhcp-helper
via the -sf
parameter,
which seems to communicate back with NetworkManager
via D-Bus.
NetworkManager
can be configured to use dhcpcd
or internal
, as DHCP clients instead of dhclient
.
FIXME: ConfiguringNetworkManager
to useinternal
did not work (why?). Is it using systemd DHCP client code? (libsystemd-network <https://github.com/NetworkManager/NetworkManager/tree/master/src/systemd/src/libsystemd-network`>`_ is included in ``NetworkManager
source code, which is insystemd
code). It does not work either withdhcpcd
: NetworkManager[12712]: <warn> [1493146345.7994] dhcp-init: DHCP client 'dhcpcd' not available
dhclient
returns¶When dhclient
call the script, by default /sbin/dhcpcanon-script
,
or when called by NetworkManager
, nm-dhcp-helper
, it pass environment
variables.
FIXME: Are these variables documented somewhere?.
In man dhclient-script
there is the list of values that the variable reason
can take:
The following reasons
are currently defined: MEDIUM, PREINIT, BOUND, RENEW, REBIND, REBOOT,
EXPIRE, FAIL, STOP, RELEASE, NBI and TIMEOUT.
But there are more variables.
By setting RUN=yes
in /etc/dhcp/debug
, these variables are found
in /tmp/dhclient-script.debug
:
reason='PREINIT'
interface=
--------------------------
reason='REBOOT'
interface=
new_ip_address=
new_network_number=
new_subnet_mask=
new_broadcast_address=
new_routers=
new_domain_name=
new_domain_name_servers=
Looking at the code dhclient v4.3.5 there seem to be more variables.
dhcpcanon
required modifications¶If dhcpcanon
accepts the same arguments as dhclient
and calls
the script nm-dhcp-helper
with the same environment
variables as dhclient
, it should be integrated.
FIXME: however for some reason this generates D-Bus errors.
dhcpcanon
could also implement the D-Bus input/output that
NetworkManager
needs.
There’s a NetworkManager D-Bus API specification.
There’s also a Python API, python-networkmanager,
so dhcpcanon
could communicate directly with NetworkManager
instead
communicating with nm-dhcp-helper
.
Debugging:
[logging] level=DEBUG
It is not possible to set dhcp-send-hostname
(Bug 768076 - No way to set dhcp-send-hostname globally)
globally.
To modify dhcp-send-hostname
per interface:
nmcli connection modify “Wired connection” ipv4.dhcp-send-hostname no nmcli connection show “Wired connection”
There is currently no way that when a new device is create it defaults to a configuration.
dhcpcanon.dhcpcapfsm |
|
dhcpcanon.dhcpcap |
|
dhcpcanon.dhcpcaplease |
|
dhcpcanon.clientscript |
|
dhcpcanon.timers |
Timers for the DHCP client implementation of the Anonymity Profile ([RFC 7844]). |
dhcpcanon.dhcpcaputils |
|
dhcpcanon.constants |
Constants for the DHCP client implementation of the Anonymity Profile ([RFC 7844]). |
dhcpcanon.conflog |
Logging configuration. |
Timers for the DHCP client implementation of the Anonymity Profile ([RFC 7844]).
dhcpcanon.timers.
gen_delay_selecting
()[source]¶Generate the delay in seconds in which the DISCOVER will be sent.
The client SHOULD wait a random time between one and ten seconds to
desynchronize the use of DHCP at startup.
dhcpcanon.timers.
gen_renewing_time
(lease_time, elapsed=0)[source]¶Generate RENEWING time.
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_renew
(lease)[source]¶Generate time in seconds to retransmit DHCPREQUEST.
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.
might retransmit the
DHCPREQUEST message four times, for a total delay of 60 seconds
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.
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
Logging configuration.