Partial

RFC 2131 - Dynamic Host Configuration Protocol

Every requirement this repository extracted from RFC 2131, the tests bound to it, and what a reader has verified about them. This summary is enrolled and gated by ./le rfc check.

Overview

Positive

what Ze has

Tested both ways38.0%27 of 71 gated MUSTs

a positive test proves Ze does what the requirement demands and a negative one proves it refuses what the requirement forbids

One polarity plus reason7.0%5 of 71 gated MUSTs

the requirement admits no counter-case, so one polarity plus a recorded reason is the whole proof available for it

One polarity, unexcused0.0%0 of 71 gated MUSTs

one direction is tested, the other is neither tested nor excused, and nothing states which

Partial proof; remaining gap0.0%0 of 71 gated MUSTs

scoped tests exist; the remaining obligation is unmet or unproven, with zero whole-requirement credit

Proven by a recorded break56.8%42 of 74 tagged units, 0 escaped and 5 lapsed

a red was observed once under a recorded procedure, and the unit, the claim and the producer it rested on still hash to what was recorded. The break is not re-run. A test pair is not a proof until one has been observed

Neutral

measures that are neither good news nor bad

Gated MUSTs71of 109 this summary declares

MUST-level requirements the gate HOLDS. A population, not a result: the shares beside it are what says how Ze stands

Out of scope24of 71 gated MUSTs

an obligation that does not bind Ze. A {not-applicable} annotation says it never bound; a {feature-declined} annotation says its condition is an optional feature Ze does not offer, and quotes the RFC sentence that makes it optional. Scope, not coverage: it stays in the denominator every share on this page is taken over

Not applicable33.8%24 of 71 gated MUSTs

a {not-applicable} annotation says the obligation does not bind Ze, so no test is owed for it. It stays in the denominator every share here is taken over

Met below Ze0.0%0 of 71 gated MUSTs

a {lower-layer} annotation says a layer under Ze performs the behavior, on state Ze installs into that layer, and names the producer that installs it. The obligation binds Ze and is met; Ze proves none of it, because its own boundary carries no value the behavior reads

Optional feature declined0.0%0 of 71 gated MUSTs

a {feature-declined} annotation says the obligation is conditional on a feature the RFC makes optional and Ze does not offer, and it quotes the sentence that makes it optional. The condition is false, so nothing is owed and nothing is missing. It stays in the denominator every share here is taken over

Negative

what Ze owes

No test at all21.1%15 of 71 gated MUSTs

no test carries the requirement id, whether or not a gap states why

The 8 shares marked as a part above are the whole of the 71 gated MUSTs: they add to 100%. Proven by a recorded break is a share of TAGGED UNITS, a different population, so it is not one of them.

How to read the colors

A color names what the measure MEANS, not how well Ze scores on it. Green is a good outcome at any value, red is a bad one, and neither a population nor a scope count is an outcome, so both take no color. The number under the label is what says how far Ze has got.

CardTone hereWhy that color
Gated MUSTs neutral no color: a population is a scale, and a larger one is neither good news nor bad. It is the accounting total
Out of scope neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Tested both ways ok green at every value: a test pair is the outcome this gate exists to produce, and the share under the label is what says how far Ze has got
One polarity plus reason ok green at every value: where no counter-case exists, one polarity IS the complete answer, and a recorded reason is what the gate demands beside it
One polarity, unexcused ok green at zero, RED above it: half a proof with no reason for the other half
Partial proof; remaining gap ok green at zero, RED above it: a tested clause cannot prove the whole requirement
No test at all bad green at zero, RED above it: a binding obligation nothing exercises is a claim with nothing behind it, whether or not a reason is stated
Not applicable neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Met below Ze neutral no color: an obligation met below Ze is neither a test Ze wrote nor work Ze owes, and the two green shares above are what says how much Ze proves itself
Optional feature declined neutral no color: an obligation whose condition Ze never meets is neither an achievement nor a failure. The absent FEATURE is disclosed on the RFC's own status row, as an implementation gap a later scope decision can revisit
Proven by a recorded break ok green at every value: an observed break is the outcome the discrimination gate exists to produce. The denominator is TAGGED UNITS, not obligations, so this share is not one of the parts above
Audit verdicts warn RED on the first weak, wrong or unimplemented verdict, amber while a verdict is no longer current or a gated MUST is unjudged, green when every one is judged sound and current

At a glance

FieldValue
Public status Partial
Enrolment Enrolled
Requirements 109
Gated MUST-level 71
Not applicable, so out of scope 24
Declared gaps 15
Declared gaps a test demonstrates 0
Gated with no test 0
Nightly-only evidence 0
Test tags 76
Tagged units 74
Recorded audit verdicts 21
Discrimination records 47
Summary rfc/short/rfc2131.md
Requirement shard rfc/requirements/rfc2131.md
RFC text rfc/full/rfc2131.txt

Enrolment

Enrolled: Dynamic Host Configuration Protocol

What the public ledger says

Status: Partial

What the ledger says is covered Both roles. Server: DORA, leases, static mappings, PXE support -- every OFFER/ACK/NAK carries the server identifier, OFFER and ACK carry the lease time and ordered T1/T2 timers, no client-only option (50, 55, 57, 61) is ever echoed back, a NAK carries nothing beyond the message type and server identifier, the magic cookie is required on input and emitted on output, and options are read and written strictly inside the options field. Client: the iface-dhcp plugin (internal/plugins/iface/dhcp/) runs a long-lived DHCPv4 client per interface unit -- ze owns the lease state machine (INIT, BOUND, RENEWING and REBINDING on deadlines from the instant each DHCPREQUEST was sent, the server's ordered T1/T2 or the defaults, the section 4.4.5 retransmission schedule, DHCPNAK restart, expiry teardown, address and default-route installation with route retry), sends the RENEWING DHCPREQUEST by unicast to the server identifier from the leased address and the REBINDING one by broadcast, accepts a REBINDING answer from any server, refuses an ACK without a lease time, and authors options 12 and 61 on every DHCPREQUEST, while DORA and the base of each extending DHCPREQUEST (NewRenewFromAck) are built by the vendored nclient4 library. Tests bound per requirement in rfc/short/rfc2131.md.
What the ledger says remains

Fifteen MUST gaps, each annotated in rfc/short/rfc2131.md.

Server: an OFFER to a client that already holds a binding restarts the lease duration instead of returning the expiration time already assigned (RFC2131-4.3.1-10); DHCPNAK delivery (RFC2131-4.3.2-1 unicasts to a non-zero ciaddr instead of broadcasting, RFC2131-4.3.2-2 never forces the broadcast bit behind a relay); INIT-REBOOT for an unknown client draws an ACK rather than silence (RFC2131-4.3.2-3); a declined address is handed back to the client that declined it (RFC2131-4.3.3-1); only one address per subnet is accepted as the server identifier (RFC2131-4.1-1); with no default-router configured the server identifier falls back to a pool address or the subnet network address, neither of which the server answers on (RFC2131-4.1-2); the client identifier option 61 is never read, so every client is keyed by chaddr (RFC2131-4.2-1); the Parameter Request List is never parsed, so the section 4.3.1 selection rules govern no code path (RFC2131-4.3.1-1, 4.3.1-3, 4.3.1-5); and the vendor class is matched by "PXEClient:" prefix rather than exactly (RFC2131-4.3.1-7).

Client: the configured client-id is emitted with no uniqueness check (RFC2131-2-1); an address found in use is kept rather than declined, and no DHCPDECLINE path exists (RFC2131-3.1-7); and DORA retransmission doubles the timeout with no randomization (RFC2131-4.1-8). DHCPINFORM is answered by no code path and sent by none, the server emits no option overload (52), and the client neither emits nor honors one, and the remaining client-role MUSTs are not-applicable because ze produces none of the governed bytes: the vendored nclient4 library constructs them, or ze never enters the state (INIT-REBOOT, DECLINE, RELEASE, INFORM). The client issues no ARP request for an offered address, so the section 4.4.1 rules for that ARP request govern no code path.

Coverage

BucketCountWhat it counts
Positive and negative tests 27 one part of the gated population
Annotated (including scoped evidence) 44 one part of the gated population
One polarity only 0 one part of the gated population
No test and no annotation 0 one part of the gated population
Partial proof; remaining gap (subset of annotated; zero whole-requirement credit) 0 an overlay: each of these is also counted by the part it falls in
Evidence that runs nightly only 0 an overlay: each of these is also counted by the part it falls in
Derived from other rows 0 outside the gated population: each asserts nothing and derives its state from the rows it names, which the parts above already count
Gated MUST-level requirements71every gated MUST falls in exactly one bucket above

Positive and negative tests (27): RFC2131-4.3-4, RFC2131-4.3-5, RFC2131-4.3-6, RFC2131-4.3-7, RFC2131-4.3-8, RFC2131-4.3-9, RFC2131-3.2-4, RFC2131-4.2-2, RFC2131-2-2, RFC2131-3.1-5, RFC2131-4.4.5-1, RFC2131-3-1, RFC2131-4.1-3, RFC2131-4.1-6, RFC2131-4.1-7, RFC2131-4.1-15, RFC2131-4.1-10, RFC2131-2-3, RFC2131-4.4.5-2, RFC2131-4.4.5-3, RFC2131-4.3.1-2, RFC2131-4.3.1-4, RFC2131-4.3.1-6, RFC2131-4.3.2-5, RFC2131-4.4.5-5, RFC2131-4.4.5-6, RFC2131-4.4.5-7

Annotated (including scoped evidence) (44): RFC2131-4.3-1, RFC2131-4.3-2, RFC2131-4.3-3, RFC2131-4.3.5-1, RFC2131-4.3.2-1, RFC2131-4.3.2-2, RFC2131-4.3.2-3, RFC2131-4.3.3-1, RFC2131-4.1-1, RFC2131-4.1-2, RFC2131-4.2-1, RFC2131-2-1, RFC2131-3.1-1, RFC2131-3.1-2, RFC2131-3.1-3, RFC2131-3.1-4, RFC2131-3.2-1, RFC2131-3.1-6, RFC2131-3.1-7, RFC2131-4.1-4, RFC2131-4.1-5, RFC2131-4.1-8, RFC2131-4.1-9, RFC2131-3.4-1, RFC2131-2-4, RFC2131-3.5-1, RFC2131-3.1-8, RFC2131-4.3.1-1, RFC2131-4.3.1-3, RFC2131-4.3.1-5, RFC2131-4.3.1-7, RFC2131-4.4.1-1, RFC2131-4.4.2-1, RFC2131-4.4.2-2, RFC2131-4.4.3-1, RFC2131-3.2-3, RFC2131-4.4-1, RFC2131-4.4-2, RFC2131-4.4-3, RFC2131-3-2, RFC2131-3.6-1, RFC2131-4.1-16, RFC2131-4.4.1-4, RFC2131-4.3.1-10

Requirements

RequirementLevelSectionTests
RFC2131-4.3-1Server identifier MUST MUST MUST (§4.3)
MUST 4.3
negativeno testno negative test

{single-polarity}: every reply path appends option 54 unconditionally -- buildReply at internal/plugins/dhcpserver/handler.go:246 and buildNak at handler.go:349 -- so no input suppresses the server identifier and there is no omission to assert negatively

RFC2131-4.3-2IP address lease time MUST (§4.3)
MUST 4.3
positiveunit/verifyTestLeaseTimeInOfferAndAck
negativeno testno negative test

{single-polarity}: the lease time is appended to every OFFER and ACK unconditionally (buildReply internal/plugins/dhcpserver/handler.go:271-273, inside the OFFER/ACK branch opened at handler.go:248), so no input yields a DHCPOFFER without option 51 to assert negatively

RFC2131-4.3-3IP address lease time MUST MUST (DHCPREQUEST) (§4.3)
MUST 4.3
positiveunit/verifyTestLeaseTimeInOfferAndAck
negativeno testno negative test

{single-polarity}: the lease time is appended to every OFFER and ACK unconditionally (buildReply internal/plugins/dhcpserver/handler.go:271-273, inside the OFFER/ACK branch opened at handler.go:248), so no DHCPREQUEST yields a DHCPACK without option 51 to assert negatively

RFC2131-4.3-4IP address lease time MUST MUST (DHCPREQUEST) MUST NOT (§4.3)
MUST NOT 4.3
RFC2131-4.3-5Requested IP address MUST NOT MUST NOT MUST NOT (§4.3)
MUST NOT 4.3
RFC2131-4.3-6Client identifier MUST NOT MUST NOT (§4.3)
MUST NOT 4.3
RFC2131-4.3-7Parameter request list MUST NOT MUST NOT MUST NOT (§4.3)
MUST NOT 4.3
RFC2131-4.3-8Maximum message size MUST NOT MUST NOT MUST NOT (§4.3)
MUST NOT 4.3
RFC2131-4.3-9All others MAY MAY MUST NOT (§4.3)
MUST NOT 4.3
RFC2131-4.3.5-1The server MUST NOT send a lease expiration time to the client (§4.3.5)
MUST NOT 4.3.5
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze answers no DHCPINFORM at all -- the message-type switch in handle (internal/plugins/dhcpserver/handler.go:121-134) dispatches DISCOVER, REQUEST, RELEASE and DECLINE, and every other type including msgInform (handler.go:37) falls to the default branch that returns nil, so ze builds no DHCPINFORM response at all

RFC2131-4.3.2-1If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on the same subnet as the server. The server MUST broadcast the DHCPNAK message to the 0xffffffff broadcast address (§4.3.2)
MUST 4.3.2
positiveno testno positive test
negativeno testno negative test

{gap}: with giaddr zero the delivery path unicasts a DHCPNAK to a non-zero ciaddr instead of broadcasting -- responseAddr tests giaddr, then ciaddr, before it ever reaches the broadcast decision (internal/plugins/dhcpserver/register.go:275-298) and never special-cases the NAK message type, so a REQUEST whose ciaddr is on-subnet and whose requested address is off-subnet is NAKed to ciaddr:68

RFC2131-4.3.2-2If 'giaddr' is set in the DHCPREQUEST message, the client is on a different subnet. The server MUST set the broadcast bit in the DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the client (§4.3.2)
MUST 4.3.2
positiveno testno positive test
negativeno testno negative test

{gap}: buildNak copies the client's flags word verbatim (internal/plugins/dhcpserver/handler.go:339) and never forces the BROADCAST bit, so a DHCPNAK relayed through a non-zero giaddr leaves the server with the broadcast bit clear whenever the client left it clear

RFC2131-3.2-4Otherwise, the server MUST send the DHCPNAK message to the IP address of the BOOTP relay agent, as recorded in 'giaddr'. (§3.2)
MUST 3.2
positiveunit/verifyTestNakDeliveredToRelayAgent
negativeunit/verifyTestNakDeliveredToRelayAgent
RFC2131-4.3.2-3If the DHCP server has no record of this client, then it MUST remain silent (§4.3.2)
MUST 4.3.2
positiveno testno positive test
negativeno testno negative test

{gap}: the INIT-REBOOT branch commits a binding for any in-subnet requested address without consulting the lease table (handleRequest internal/plugins/dhcpserver/handler.go:178-183 calls commitBinding at handler.go:194), so a client the server holds no record of draws a DHCPACK rather than silence

RFC2131-4.3.3-1The server MUST mark the network address as not available (§4.3.3)
MUST 4.3.3
positiveno testno positive test
negativeno testno negative test

{gap}: markUnavailable sets the pool bit and the static set for the declined address (internal/plugins/dhcpserver/pool.go:144-163), but the declining client's MAC-to-address cache entry survives -- pool.release returns early for a staticSet address (pool.go:174-177) -- so pool.allocate hands that same declined address back to that client on its next DISCOVER (pool.go:68-72)

RFC2131-4.1-1A server with multiple network addresses MUST be prepared to to accept any of its network addresses as identifying that server in a DHCP message. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{gap}: each handler accepts exactly one address as its server identifier -- handleRequest discards a REQUEST whose option 54 differs from its own serverIP (internal/plugins/dhcpserver/handler.go:167-169) -- and that address is the single per-subnet value derived at register.go:93-101, so a REQUEST naming another of the server's own addresses is silently dropped

RFC2131-4.1-2To accommodate potentially incomplete network connectivity, a server MUST choose an address as a 'server identifier' that, to the best of the server's knowledge, is reachable from the client. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{gap}: with no default-router configured for a subnet the server identifier is not an address the server answers on -- register.go:93 prefers sub.DefaultRouter, which parseSubnet leaves unset when the leaf is absent (internal/plugins/dhcpserver/config.go:189-195), and falls back to the first pool address (internal/plugins/dhcpserver/register.go:95-97), which the server itself hands out to a client, or to the subnet network address (register.go:99-101), which is no host at all; buildReply then emits that value as option 54 (internal/plugins/dhcpserver/handler.go:246), so a client unicasting to it reaches nothing

RFC2131-4.2-1If the client supplies a 'client identifier', the client MUST use the same 'client identifier' in all subsequent messages, and the server MUST use that identifier to identify the client. (§4.2)
MUST 4.2
positiveno testno positive test
negativeno testno negative test

{gap}: ze never reads the client identifier -- option 61 is absent from the option codes at internal/plugins/dhcpserver/handler.go:41-61 and no parse call asks for it -- and keys every binding on the hardware address instead (extractMAC handler.go:456, leaseTable byMAC lease.go:23, pool.macToAddr pool.go:22), so a client that supplies a client identifier is still identified by chaddr

RFC2131-4.2-2If the client does not provide a 'client identifier' option, the server MUST use the contents of the 'chaddr' field to identify the client. (§4.2)
MUST 4.2
RFC2131-2-1The 'client identifier' chosen by a DHCP client MUST be unique to that client within the subnet to which the client is attached. (§2)
MUST 2
positiveno testno positive test
negativeno testno negative test

{gap}: ze's client emits the operator-configured client identifier verbatim and nothing derives or checks it -- v4RequestModifiers appends OptClientIdentifier([]byte(c.config.ClientID)) (internal/plugins/iface/dhcp/dhcp_v4_linux.go) from the config leaf read into ClientID in internal/component/iface/config.go and carried to the client factory in internal/component/iface/register.go, and no validator constrains the value, so two units on one subnet configured with the same client-id emit colliding identifiers

RFC2131-2-2If the client uses a 'client identifier' in one message, it MUST use that same identifier in all subsequent messages, to ensure that all servers correctly identify the client. (§2)
MUST 2
RFC2131-3.1-1The client broadcasts a DHCPREQUEST message that MUST include the 'server identifier' option to indicate which server it has selected (§3.1)
MUST 3.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze hands SELECTING message construction to the vendored library -- nclient4Exchanger.acquire calls client.RequestFromOffer (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go), which builds the REQUEST in NewRequestFromOffer (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4packet.go) where the server identifier is copied from the OFFER; ze contributes only the hostname, client-id and reserved-flags modifiers (v4RequestModifiers, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and authors none of those bytes

RFC2131-3.1-2The 'requested IP address' option MUST be set to the value of 'yiaddr' in the DHCPOFFER message from the server. (§3.1)
MUST 3.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze hands SELECTING message construction to the vendored library -- nclient4Exchanger.acquire calls client.RequestFromOffer (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go), which builds the REQUEST in NewRequestFromOffer (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4packet.go) where the requested IP address option is set from the OFFER's yiaddr; ze contributes only the hostname, client-id and reserved-flags modifiers (v4RequestModifiers, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and authors none of those bytes

RFC2131-3.1-3'requested IP address' option MUST be filled in with client's notion of its previously assigned address. (§4.3.2)
MUST 4.3.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST

RFC2131-3.1-4DHCPREQUEST generated during INIT-REBOOT state: 'server identifier' MUST NOT be filled in (§4.3.2)
MUST NOT 4.3.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST

RFC2131-3.1-5'server identifier' MUST NOT be filled in, 'requested IP address' option MUST NOT be filled in (§4.3.2)
MUST NOT 4.3.2
RFC2131-3.2-1As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. (§3.2)
MUST NOT 3.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST

RFC2131-3.1-6If the client used a 'client identifier' when it obtained the lease, it MUST use the same 'client identifier' in the DHCPRELEASE message. (§3.1, §3.2)
MUST 3.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client sends no DHCPRELEASE, so no ze path builds the message whose fields this governs -- teardownV4 ends a lease by removing the address and default route locally (internal/plugins/iface/dhcp/dhcp_v4_linux.go, teardownV4), and nclient4's Release (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go:26) is called nowhere in ze

RFC2131-3.1-7If the client detects that the address is already in use (e.g., through the use of ARP), the client MUST send a DHCPDECLINE message to the server and restarts the configuration process. (§3.1, §3.2)
MUST 3.1
positiveno testno positive test
negativeno testno negative test

{gap}: ze's client installs the ACKed address without checking it is free and has no DHCPDECLINE path -- installV4Lease goes straight from the ACK to ReplaceAddressWithLifetime (internal/plugins/iface/dhcp/dhcp_v4_linux.go) with no probe of the address, and neither ze nor the vendored nclient4 client contains a DECLINE producer, so an address found in use is kept rather than declined

RFC2131-4.4.5-1If the lease expires before the client receives a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requests network initialization parameters as if the client were uninitialized. (§4.4.5)
MUST 4.4.5
RFC2131-3-1The first four octets of the 'options' field of the DHCP message contain the (decimal) values 99, 130, 83 and 99, respectively (§3)
MUST 3
RFC2131-4.1-3The last option must always be the 'end' option. (§4.1)
MUST 4.1
RFC2131-4.1-4If the options in a DHCP message extend into the 'sname' and 'file' fields, the 'option overload' option MUST appear in the 'options' field, with value 1, 2 or 3, as specified in RFC 1533. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze neither emits nor honors option overload (52) -- buildReply and buildNak leave sname and file zeroed (internal/plugins/dhcpserver/handler.go:220-290 and 333-354) and every option reader starts at pkt[240:], the options field alone (parseMsgType handler.go:367, parseOptionAddr handler.go:386, parseOptionBytes handler.go:471), so no option ever lives in the sname or file field

RFC2131-4.1-5The options in the 'sname' and 'file' fields (if in use as indicated by the 'options overload' option) MUST begin with the first octet of the field, MUST be terminated by an 'end' option, and MUST be followed by 'pad' options to fill the remainder of the field. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze neither emits nor honors option overload (52) -- buildReply and buildNak leave sname and file zeroed (internal/plugins/dhcpserver/handler.go:220-290 and 333-354) and every option reader starts at pkt[240:], the options field alone (parseMsgType handler.go:367, parseOptionAddr handler.go:386, parseOptionBytes handler.go:471), so no option ever lives in the sname or file field

RFC2131-4.1-6Any individual option in the 'options', 'sname' and 'file' fields MUST be entirely contained in that field. (§4.1)
MUST 4.1
RFC2131-4.1-7The options in the 'options' field MUST be interpreted first, so that any 'option overload' options may be interpreted. (§4.1)
MUST 4.1
RFC2131-4.1-15The 'file' field MUST be interpreted next (if the 'option overload' option indicates that the 'file' field contains DHCP options), followed by the 'sname' field. (§4.1)
MUST 4.1
RFC2131-4.1-8The client MUST adopt a retransmission strategy that incorporates a randomized exponential backoff algorithm to determine the delay between retransmissions. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{gap}: ze's client retransmits on a doubling timeout with no randomization -- the acquiring exchange builds its client with no ClientOpt (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go, nclient4Exchanger.acquire), so DORA runs the vendored defaults of a 5 second timeout over 3 tries (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:32, 35, 183) through retryFn, which only doubles the timeout between tries (client.go:649-669); the extending DHCPREQUEST is outside this gap, sent once per attempt on the section 4.4.5 schedule (internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4NextAttempt)

RFC2131-4.1-9A DHCP client MUST choose 'xid's in such a way as to minimize the chance of using an 'xid' identical to one used by another client. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: the transaction ID is drawn inside the vendored library -- every message ze's client sends is built through dhcpv4.New (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:144-150), which takes the xid from crypto/rand via GenerateTransactionID (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:121-139); ze calls DiscoverOffer and RequestFromOffer (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go, nclient4Exchanger.acquire) and builds every extending DHCPREQUEST with NewRenewFromAck (internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4ExtendRequest), and authors no xid

RFC2131-4.1-10DHCP clients MUST use the IP address provided in the 'server identifier' option for any unicast requests to the DHCP server. (§4.1)
MUST 4.1
RFC2131-3.4-1The server SHOULD check the network address in a DHCPINFORM message for consistency, but MUST NOT check for an existing lease. (§3.4)
MUST NOT 3.4
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze answers no DHCPINFORM at all -- the message-type switch in handle (internal/plugins/dhcpserver/handler.go:121-134) dispatches DISCOVER, REQUEST, RELEASE and DECLINE, and every other type including msgInform (handler.go:37) falls to the default branch that returns nil, so ze builds no DHCPINFORM response at all, so no response path exists that could consult an existing lease

RFC2131-2-3The remaining bits of the flags field are reserved for future use. They MUST be set to zero by clients and ignored by servers and relay agents. (§2)
MUST 2
RFC2131-2-4A DHCP client must be prepared to receive DHCP messages with an 'options' field of at least length 312 octets. (§2)
MUST 2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze reads no DHCP bytes itself -- the receive path is the vendored library's receiveLoop, which reads each datagram into a MaxMessageSize (1500 octet) buffer before decoding (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:256-271, MaxMessageSize at client.go:38), and ze only consumes the decoded result of client.RequestFromOffer and client.SendAndRead (nclient4Exchanger, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go); the RENEWING exchange's v4UnicastConn hands the device's raw-socket datagrams to that same receiveLoop

RFC2131-3.5-1If the client includes a list of parameters in a DHCPDISCOVER message, it MUST include that list in any subsequent DHCPREQUEST messages. (§3.5)
MUST 3.5
positiveno testno positive test
negativeno testno negative test

{not-applicable}: the parameter request list is written by the vendored library, the same list in both messages -- NewDiscovery (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:198-209) and NewRequestFromOffer (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:256-270) each add the identical WithRequestedOptions set, and ze passes only hostname and client-id modifiers (internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4RequestModifiers), so it authors no request list

RFC2131-4.4.5-2T1 MUST be earlier than T2 (§4.4.5)
MUST 4.4.5
RFC2131-4.4.5-3T2, which, in turn, MUST be earlier than the time at which the client's lease will expire. (§4.4.5)
MUST 4.4.5
RFC2131-3.1-8To help ensure that any BOOTP relay agents forward the DHCPREQUEST message to the same set of DHCP servers that received the original DHCPDISCOVER message, the DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP broadcast address as the original DHCPDISCOVER message. (§3.1)
MUST 3.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: the secs field and the broadcast flag of the SELECTING REQUEST are the vendored library's -- it leaves secs zero in both the DISCOVER and the REQUEST (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:164-180 sets no secs) and copies the flags word across with WithReply (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:258, vendor/github.com/insomniacslk/dhcp/dhcpv4/modifiers.go:56-68), while ze's DORA call and its modifiers touch neither (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go, nclient4Exchanger.acquire; internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4RequestModifiers)

RFC2131-3.1-9When allocating a new address, servers SHOULD check that the offered network address is not already in use; e.g., the server may probe the offered address with an ICMP Echo Request. (§3.1)
SHOULD 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.4-1The server SHOULD retain a record of the client's initialization parameters for possible reuse in response to subsequent requests from the client. (§4.3.4)
SHOULD 4.3.4
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-10The server SHOULD mark an address offered to a client in a DHCPOFFER message as available if the server receives no DHCPREQUEST message from that client. (§3.1)
SHOULD 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.2-4If the DHCP server detects that the client is on the wrong net (i.e., the result of applying the local subnet mask or remote subnet mask (if 'giaddr' is not zero) to 'requested IP address' option value doesn't match reality), then the server SHOULD send a DHCPNAK message to the client. (§4.3.2)
SHOULD 4.3.2
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.3-2SHOULD notify the local system administrator of a possible configuration problem. (§4.3.3)
SHOULD 4.3.3
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.5-2SHOULD NOT fill in 'yiaddr'. (§4.3.5)
SHOULD NOT 4.3.5
positiveno testno positive test
negativeno testno negative test
RFC2131-3.4-2The servers SHOULD unicast the DHCPACK reply to the address given in the 'ciaddr' field of the DHCPINFORM message. (§3.4)
SHOULD 3.4
positiveno testno positive test
negativeno testno negative test
RFC2131-3.4-3The server SHOULD check the network address in a DHCPINFORM message for consistency (§3.4)
SHOULD 3.4
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-11Any configuration parameters in the DHCPACK message SHOULD NOT conflict with those in the earlier DHCPOFFER message to which the client is responding. (§3.1)
SHOULD NOT 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-12The server SHOULD NOT check the offered network address at this point. (§3.1)
SHOULD NOT 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-13The client SHOULD perform a final check on the parameters (e.g., ARP for allocated network address) (§3.1)
SHOULD 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-14The client SHOULD wait a minimum of ten seconds before restarting the configuration process to avoid excessive network traffic in case of looping. (§3.1)
SHOULD 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-15The client SHOULD notify the user that the initialization process has failed and is restarting. (§3.1)
SHOULD 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.5-2The client SHOULD include the 'maximum DHCP message size' option to let the server know how large the server may make its DHCP messages. (§3.5)
SHOULD 3.5
positiveno testno positive test
negativeno testno negative test
RFC2131-3.7-1A client SHOULD use DHCP to reacquire or verify its IP address and network parameters whenever the local network parameters may have changed; e.g., at system boot time or after a disconnection from the local network, as the local network configuration may change without the client's or user's knowledge. (§3.7)
SHOULD 3.7
positiveno testno positive test
negativeno testno negative test
RFC2131-2-5The TCP/IP software SHOULD accept and forward to the IP layer any IP packets delivered to the client's hardware address before the IP address is configured (§2)
SHOULD 2
positiveno testno positive test
negativeno testno negative test
RFC2131-4.1-11A client that cannot receive unicast IP datagrams until its protocol software has been configured with an IP address SHOULD set the BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or DHCPREQUEST messages that client sends. (§4.1)
SHOULD 4.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.1-12A server or relay agent sending or relaying a DHCP message directly to a DHCP client (i.e., not to a relay agent specified in the 'giaddr' field) SHOULD examine the BROADCAST bit in the 'flags' field. If this bit is set to 1, the DHCP message SHOULD be sent as an IP broadcast using an IP broadcast address (preferably 0xffffffff) as the IP destination address and the link-layer broadcast address as the link-layer destination address. (§4.1)
SHOULD 4.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.4.5-4Times T1 and T2 SHOULD be chosen with some random "fuzz" around a fixed value, to avoid synchronization of client reacquisition. (§4.4.5)
SHOULD 4.4.5
positiveno testno positive test
negativeno testno negative test
RFC2131-4.1-13the 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. (§4.1)
SHOULD 4.1
positiveno testno positive test
negativeno testno negative test
RFC2131-2.2-1As a consistency check, the allocating server SHOULD probe the reused address before allocating the address, e.g., with an ICMP echo request (§2.2)
SHOULD 2.2
positiveno testno positive test
negativeno testno negative test
RFC2131-2.2-2the client SHOULD probe the newly received address, e.g., with ARP. (§2.2)
SHOULD 2.2
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-16The DHCPDISCOVER message MAY include options that suggest values for the network address and lease duration. (§3.1)
MAY 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.1-17A server MAY choose to mark addresses offered to clients in DHCPOFFER messages as unavailable. (§3.1)
MAY 3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.2-3a server MAY, for administrative reasons, assign an address other than the one requested, or may refuse to allocate an address to a particular client even though free addresses are available. (§4.3.1)
MAY 4.3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.1-14A server with multiple network address (e.g., a multi-homed host) MAY use any of its network addresses in outgoing DHCP messages. (§4.1)
MAY 4.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3.2-2If the client receives neither a DHCPACK or a DHCPNAK message after employing the retransmission algorithm, the client MAY choose to use the previously allocated network address and configuration parameters for the remainder of the unexpired lease. (§3.2)
MAY 3.2
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.1-1The configuration parameters MUST be selected by applying the following rules in the order given below. (§4.3.1)
MUST 4.3.1
positiveno testno positive test
negativeno testno negative test

{gap}: ze applies no parameter-selection procedure -- buildReply emits one fixed option set in one fixed order (internal/plugins/dhcpserver/handler.go:245-285) and the parameter request list is never parsed (optParamReqList is defined at handler.go:52 and read nowhere in production), so the ordered rules of Section 4.3.1 govern no ze code path

RFC2131-4.3.1-2-- IF the server has been explicitly configured with a default value for the parameter, the server MUST include that value in an appropriate option in the 'option' field, ELSE (§4.3.1)
MUST 4.3.1
RFC2131-4.3.1-3-- IF the server recognizes the parameter as a parameter defined in the Host Requirements Document, the server MUST include the default value for that parameter as given in the Host Requirements Document in an appropriate option in the 'option' field, ELSE (§4.3.1)
MUST 4.3.1
positiveno testno positive test
negativeno testno negative test

{gap}: ze returns only the values its own subnet configuration holds (buildReply internal/plugins/dhcpserver/handler.go:245-285); it reads no parameter request list (optParamReqList handler.go:52 is parsed nowhere in production) and carries no Host Requirements defaults, so a recognized parameter the client requests draws no default value

RFC2131-4.3.1-4The server MUST NOT return a value for that parameter, (§4.3.1)
MUST NOT 4.3.1
RFC2131-4.3.1-5The server MUST supply as many of the requested parameters as possible and MUST omit any parameters it cannot provide. (§4.3.1)
MUST 4.3.1
positiveno testno positive test
negativeno testno negative test

{gap}: the parameter request list is never parsed (optParamReqList internal/plugins/dhcpserver/handler.go:52 is read nowhere in production), so ze supplies its fixed configured option set (buildReply handler.go:245-285) rather than as many of the client's requested parameters as it can

RFC2131-4.3.1-6The server MUST include each requested parameter only once unless explicitly allowed in the DHCP Options and BOOTP Vendor Extensions document. (§4.3.1)
MUST 4.3.1
positiveunit/verifyTestEachParameterEmittedOnce
negativeunit/verifyTestEachParameterEmittedOnce
RFC2131-4.3.1-7o Any parameters specific to this client's class (as identified by the contents of the 'vendor class identifier' option in the DHCPDISCOVER or DHCPREQUEST message), e.g., as configured by the network administrator; the parameters MUST be identified by an exact match between the client's vendor class identifiers and the client's classes identified in the server, (§4.3.1)
MUST 4.3.1
positiveno testno positive test
negativeno testno negative test

{gap}: ze identifies the vendor class by a ten-octet prefix comparison against the string PXEClient: (isPXEClient internal/plugins/dhcpserver/handler.go:493-496) rather than by an exact match against a configured class identifier, and that prefix match is what selects the class-specific options appended at handler.go:292-330

RFC2131-4.4.1-1The client MUST include its hardware address in the 'chaddr' field, if necessary for delivery of DHCP reply messages. (§4.4.1)
MUST 4.4.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: chaddr is filled by the vendored library from the bound interface -- nclient4.New resolves the interface MAC (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:199-209) and NewDiscovery/NewRequestFromOffer set it with WithHwAddr (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4packet.go); ze only names the kernel device to bind (nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go)

RFC2131-4.4.2-1The client MUST insert its known network address as a 'requested IP address' option in the DHCPREQUEST message. (§4.4.2)
MUST 4.4.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7

RFC2131-4.4.2-2The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.2)
MUST NOT 4.4.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7

RFC2131-4.4.3-1DHCPINFORM messages MUST be directed to the 'DHCP server' UDP port (§4.4.3)
MUST 4.4.3
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's client sends no DHCPINFORM -- nclient4 exposes Inform (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:483-498) and ze calls it nowhere; the exchanger uses only DiscoverOffer, RequestFromOffer and SendAndRead (nclient4Exchanger, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go)

RFC2131-4.3.2-5This message MUST be broadcast to the 0xffffffff IP broadcast address. (§4.3.2)
MUST 4.3.2
RFC2131-4.4.5-5If the client is given a new network address, it MUST NOT continue using the previous network address (§4.4.5)
MUST NOT 4.4.5
RFC2131-4.4.5-6The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.5)
MUST NOT 4.4.5
RFC2131-4.4.5-7The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.5)
MUST NOT 4.4.5
RFC2131-3.2-3As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. (§3.2)
MUST NOT 3.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST

RFC2131-4.4-1Vendor class identifier MAY MAY MUST NOT (§4.4)
MUST NOT 4.4
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7

RFC2131-4.4-2Requested IP address MAY MUST (in MUST (DISCOVER) SELECTING or (DHCPDECLINE), (§4.4)
MUST 4.4
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7

RFC2131-4.4-3Server identifier MUST NOT MUST (after MUST SELECTING) (§4.4)
MUST 4.4
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze's DHCPv4 client sends no DHCPRELEASE, so no ze path builds the message whose fields this governs -- the lease loop ends a lease by removing the address locally (teardownV4, internal/plugins/iface/dhcp/dhcp_v4_linux.go), and nclient4's Release (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go:26) is called nowhere in ze

RFC2131-4.4.3-2The client SHOULD NOT request lease time parameters. (§4.4.3)
SHOULD NOT 4.4.3
positiveno testno positive test
negativeno testno negative test
RFC2131-4.4.1-2The client SHOULD wait a random time between one and ten seconds to desynchronize the use of DHCP at startup. (§4.4.1)
SHOULD 4.4.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.4.1-3The 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. (§4.4.1)
SHOULD 4.4.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.2-6The DHCP server SHOULD check 'ciaddr' for correctness before replying to the DHCPREQUEST. (§4.3.2)
SHOULD 4.3.2
positiveno testno positive test
negativeno testno negative test
RFC2131-4.2-4The client implementation of DHCP SHOULD provide a mechanism for the user to select directly the 'vendor class identifier' values. (§4.2)
SHOULD 4.2
positiveno testno positive test
negativeno testno negative test
RFC2131-4.4.5-8In 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. (§4.4.5)
SHOULD 4.4.5
positiveunit/verifyTestV4RetransmitSchedule
negativeunit/verifyTestV4RetransmitSchedule
RFC2131-4.4.5-9If the client then receives a DHCPACK allocating that client its previous network address, the client SHOULD continue network processing. (§4.4.5)
SHOULD 4.4.5
positiveno testno positive test
negativeno testno negative test
RFC2131-4.4.5-10If the client is given a new network address, it MUST NOT continue using the previous network address and SHOULD notify the local users of the problem. (§4.4.5)
SHOULD 4.4.5
positiveno testno positive test
negativeno testno negative test
RFC2131-3.5-3If a server receives a DHCPREQUEST message with an invalid 'requested IP address', the server SHOULD respond to the client with a DHCPNAK message (§3.5)
SHOULD 3.5
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.1-8If an address is available, the new address SHOULD be chosen as follows: (§4.3.1)
SHOULD 4.3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-3-2One particular option - the "DHCP message type" option - must be included in every DHCP message. (§3)
MUST 3
positiveunit/verifyTestMessageTypeInEveryReply
negativeno testno negative test

{single-polarity}: every server reply path writes option 53 first and unconditionally -- buildReply and buildNak in internal/plugins/dhcpserver/handler.go each call safeAppendOption with optMessageType before any other option -- so no input yields a reply without the message type and there is no omission to assert negatively; ze's client messages are built by the vendored dhcpv4 builders, each of which sets option 53 (NewDiscovery and NewRequestFromOffer through client.DiscoverOffer and client.RequestFromOffer in dhcp_v4_exchange_linux.go, NewRenewFromAck through v4ExtendRequest in dhcp_v4_linux.go)

RFC2131-3.6-1A client with multiple network interfaces must use DHCP through each interface independently to obtain configuration information parameters for those separate interfaces. (§3.6)
MUST 3.6
negativeno testno negative test

{single-polarity}: ze builds one DHCPClient for each configured interface unit (newDHCPClient in internal/plugins/iface/dhcp/dhcp_linux.go), and each runs its own exchange on an nclient4 socket bound to that interface and installs its lease on that interface only (runV4 and installV4Lease in dhcp_v4_linux.go); no input reaches one client from another, so there is no shared-exchange input to refuse and assert negatively

RFC2131-4.1-16DHCP messages broadcast by a client prior to that client obtaining its IP address must have the source address field in the IP header set to 0. (§4.1)
MUST 4.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: the IP header is written inside the vendored library -- ze's client opens its socket through nclient4.New (internal/plugins/iface/dhcp/dhcp_v4_linux.go), whose NewRawUDPConn binds a UDP address with no IP (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/conn_unix.go) and whose BroadcastRawUDPConn.WriteTo builds the IPv4 header from that bound address through udp4pkt; ze authors no IP header

RFC2131-4.4.1-4If the 'xid' of an arriving DHCPOFFER message does not match the 'xid' of the most recent DHCPDISCOVER message, the DHCPOFFER message must be silently discarded. Any arriving DHCPACK messages must be silently discarded. (§4.4.1)
MUST 4.4.1
positiveno testno positive test
negativeno testno negative test

{not-applicable}: the SELECTING receive filter lives inside the vendored library -- nclient4's receiveLoop delivers a message only to the pending channel keyed by its TransactionID (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go), and client.DiscoverOffer reads the DISCOVER answer through IsMessageType(dhcpv4.MessageTypeOffer), which skips any other type; ze calls only client.DiscoverOffer, client.RequestFromOffer and client.SendAndRead (nclient4Exchanger, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and reads no reply bytes itself

RFC2131-4.3.1-9the server SHOULD NOT reuse the selected network address before the client responds to the server's DHCPOFFER message. (§4.3.1)
SHOULD NOT 4.3.1
positiveno testno positive test
negativeno testno negative test
RFC2131-4.3.1-10The server must also choose an expiration time for the lease, as follows: (§4.3.1)
MUST 4.3.1
positiveno testno positive test
negativeno testno negative test

{gap}: the first rule of the list is not followed -- a DHCPDISCOVER from a client that already holds a binding and requests no lease time is answered by handleDiscover through buildReply (internal/plugins/dhcpserver/handler.go), which writes the configured subnet LeaseTimeSec into option 51 rather than the expiration time previously assigned to that address, so every OFFER restarts the lease duration

Gaps and untested MUSTs

RequirementStateReason
RFC2131-4.3.5-1 The server MUST NOT send a lease expiration time to the client (§4.3.5) no test no test carries this requirement id; annotated {not-applicable}: ze answers no DHCPINFORM at all -- the message-type switch in handle (internal/plugins/dhcpserver/handler.go:121-134) dispatches DISCOVER, REQUEST, RELEASE and DECLINE, and every other type including msgInform (handler.go:37) falls to the default branch that returns nil, so ze builds no DHCPINFORM response at all
RFC2131-4.3.2-1 If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on the same subnet as the server. The server MUST broadcast the DHCPNAK message to the 0xffffffff broadcast address (§4.3.2) {gap}, no test with giaddr zero the delivery path unicasts a DHCPNAK to a non-zero ciaddr instead of broadcasting -- responseAddr tests giaddr, then ciaddr, before it ever reaches the broadcast decision (internal/plugins/dhcpserver/register.go:275-298) and never special-cases the NAK message type, so a REQUEST whose ciaddr is on-subnet and whose requested address is off-subnet is NAKed to ciaddr:68
RFC2131-4.3.2-2 If 'giaddr' is set in the DHCPREQUEST message, the client is on a different subnet. The server MUST set the broadcast bit in the DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the client (§4.3.2) {gap}, no test buildNak copies the client's flags word verbatim (internal/plugins/dhcpserver/handler.go:339) and never forces the BROADCAST bit, so a DHCPNAK relayed through a non-zero giaddr leaves the server with the broadcast bit clear whenever the client left it clear
RFC2131-4.3.2-3 If the DHCP server has no record of this client, then it MUST remain silent (§4.3.2) {gap}, no test the INIT-REBOOT branch commits a binding for any in-subnet requested address without consulting the lease table (handleRequest internal/plugins/dhcpserver/handler.go:178-183 calls commitBinding at handler.go:194), so a client the server holds no record of draws a DHCPACK rather than silence
RFC2131-4.3.3-1 The server MUST mark the network address as not available (§4.3.3) {gap}, no test markUnavailable sets the pool bit and the static set for the declined address (internal/plugins/dhcpserver/pool.go:144-163), but the declining client's MAC-to-address cache entry survives -- pool.release returns early for a staticSet address (pool.go:174-177) -- so pool.allocate hands that same declined address back to that client on its next DISCOVER (pool.go:68-72)
RFC2131-4.1-1 A server with multiple network addresses MUST be prepared to to accept any of its network addresses as identifying that server in a DHCP message. (§4.1) {gap}, no test each handler accepts exactly one address as its server identifier -- handleRequest discards a REQUEST whose option 54 differs from its own serverIP (internal/plugins/dhcpserver/handler.go:167-169) -- and that address is the single per-subnet value derived at register.go:93-101, so a REQUEST naming another of the server's own addresses is silently dropped
RFC2131-4.1-2 To accommodate potentially incomplete network connectivity, a server MUST choose an address as a 'server identifier' that, to the best of the server's knowledge, is reachable from the client. (§4.1) {gap}, no test with no default-router configured for a subnet the server identifier is not an address the server answers on -- register.go:93 prefers sub.DefaultRouter, which parseSubnet leaves unset when the leaf is absent (internal/plugins/dhcpserver/config.go:189-195), and falls back to the first pool address (internal/plugins/dhcpserver/register.go:95-97), which the server itself hands out to a client, or to the subnet network address (register.go:99-101), which is no host at all; buildReply then emits that value as option 54 (internal/plugins/dhcpserver/handler.go:246), so a client unicasting to it reaches nothing
RFC2131-4.2-1 If the client supplies a 'client identifier', the client MUST use the same 'client identifier' in all subsequent messages, and the server MUST use that identifier to identify the client. (§4.2) {gap}, no test ze never reads the client identifier -- option 61 is absent from the option codes at internal/plugins/dhcpserver/handler.go:41-61 and no parse call asks for it -- and keys every binding on the hardware address instead (extractMAC handler.go:456, leaseTable byMAC lease.go:23, pool.macToAddr pool.go:22), so a client that supplies a client identifier is still identified by chaddr
RFC2131-2-1 The 'client identifier' chosen by a DHCP client MUST be unique to that client within the subnet to which the client is attached. (§2) {gap}, no test ze's client emits the operator-configured client identifier verbatim and nothing derives or checks it -- v4RequestModifiers appends OptClientIdentifier([]byte(c.config.ClientID)) (internal/plugins/iface/dhcp/dhcp_v4_linux.go) from the config leaf read into ClientID in internal/component/iface/config.go and carried to the client factory in internal/component/iface/register.go, and no validator constrains the value, so two units on one subnet configured with the same client-id emit colliding identifiers
RFC2131-3.1-1 The client broadcasts a DHCPREQUEST message that MUST include the 'server identifier' option to indicate which server it has selected (§3.1) no test no test carries this requirement id; annotated {not-applicable}: ze hands SELECTING message construction to the vendored library -- nclient4Exchanger.acquire calls client.RequestFromOffer (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go), which builds the REQUEST in NewRequestFromOffer (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4packet.go) where the server identifier is copied from the OFFER; ze contributes only the hostname, client-id and reserved-flags modifiers (v4RequestModifiers, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and authors none of those bytes
RFC2131-3.1-2 The 'requested IP address' option MUST be set to the value of 'yiaddr' in the DHCPOFFER message from the server. (§3.1) no test no test carries this requirement id; annotated {not-applicable}: ze hands SELECTING message construction to the vendored library -- nclient4Exchanger.acquire calls client.RequestFromOffer (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go), which builds the REQUEST in NewRequestFromOffer (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4packet.go) where the requested IP address option is set from the OFFER's yiaddr; ze contributes only the hostname, client-id and reserved-flags modifiers (v4RequestModifiers, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and authors none of those bytes
RFC2131-3.1-3 'requested IP address' option MUST be filled in with client's notion of its previously assigned address. (§4.3.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST
RFC2131-3.1-4 DHCPREQUEST generated during INIT-REBOOT state: 'server identifier' MUST NOT be filled in (§4.3.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST
RFC2131-3.2-1 As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. (§3.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST
RFC2131-3.1-6 If the client used a 'client identifier' when it obtained the lease, it MUST use the same 'client identifier' in the DHCPRELEASE message. (§3.1, §3.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client sends no DHCPRELEASE, so no ze path builds the message whose fields this governs -- teardownV4 ends a lease by removing the address and default route locally (internal/plugins/iface/dhcp/dhcp_v4_linux.go, teardownV4), and nclient4's Release (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go:26) is called nowhere in ze
RFC2131-3.1-7 If the client detects that the address is already in use (e.g., through the use of ARP), the client MUST send a DHCPDECLINE message to the server and restarts the configuration process. (§3.1, §3.2) {gap}, no test ze's client installs the ACKed address without checking it is free and has no DHCPDECLINE path -- installV4Lease goes straight from the ACK to ReplaceAddressWithLifetime (internal/plugins/iface/dhcp/dhcp_v4_linux.go) with no probe of the address, and neither ze nor the vendored nclient4 client contains a DECLINE producer, so an address found in use is kept rather than declined
RFC2131-4.1-4 If the options in a DHCP message extend into the 'sname' and 'file' fields, the 'option overload' option MUST appear in the 'options' field, with value 1, 2 or 3, as specified in RFC 1533. (§4.1) no test no test carries this requirement id; annotated {not-applicable}: ze neither emits nor honors option overload (52) -- buildReply and buildNak leave sname and file zeroed (internal/plugins/dhcpserver/handler.go:220-290 and 333-354) and every option reader starts at pkt[240:], the options field alone (parseMsgType handler.go:367, parseOptionAddr handler.go:386, parseOptionBytes handler.go:471), so no option ever lives in the sname or file field
RFC2131-4.1-5 The options in the 'sname' and 'file' fields (if in use as indicated by the 'options overload' option) MUST begin with the first octet of the field, MUST be terminated by an 'end' option, and MUST be followed by 'pad' options to fill the remainder of the field. (§4.1) no test no test carries this requirement id; annotated {not-applicable}: ze neither emits nor honors option overload (52) -- buildReply and buildNak leave sname and file zeroed (internal/plugins/dhcpserver/handler.go:220-290 and 333-354) and every option reader starts at pkt[240:], the options field alone (parseMsgType handler.go:367, parseOptionAddr handler.go:386, parseOptionBytes handler.go:471), so no option ever lives in the sname or file field
RFC2131-4.1-8 The client MUST adopt a retransmission strategy that incorporates a randomized exponential backoff algorithm to determine the delay between retransmissions. (§4.1) {gap}, no test ze's client retransmits on a doubling timeout with no randomization -- the acquiring exchange builds its client with no ClientOpt (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go, nclient4Exchanger.acquire), so DORA runs the vendored defaults of a 5 second timeout over 3 tries (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:32, 35, 183) through retryFn, which only doubles the timeout between tries (client.go:649-669); the extending DHCPREQUEST is outside this gap, sent once per attempt on the section 4.4.5 schedule (internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4NextAttempt)
RFC2131-4.1-9 A DHCP client MUST choose 'xid's in such a way as to minimize the chance of using an 'xid' identical to one used by another client. (§4.1) no test no test carries this requirement id; annotated {not-applicable}: the transaction ID is drawn inside the vendored library -- every message ze's client sends is built through dhcpv4.New (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:144-150), which takes the xid from crypto/rand via GenerateTransactionID (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:121-139); ze calls DiscoverOffer and RequestFromOffer (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go, nclient4Exchanger.acquire) and builds every extending DHCPREQUEST with NewRenewFromAck (internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4ExtendRequest), and authors no xid
RFC2131-3.4-1 The server SHOULD check the network address in a DHCPINFORM message for consistency, but MUST NOT check for an existing lease. (§3.4) no test no test carries this requirement id; annotated {not-applicable}: ze answers no DHCPINFORM at all -- the message-type switch in handle (internal/plugins/dhcpserver/handler.go:121-134) dispatches DISCOVER, REQUEST, RELEASE and DECLINE, and every other type including msgInform (handler.go:37) falls to the default branch that returns nil, so ze builds no DHCPINFORM response at all, so no response path exists that could consult an existing lease
RFC2131-2-4 A DHCP client must be prepared to receive DHCP messages with an 'options' field of at least length 312 octets. (§2) no test no test carries this requirement id; annotated {not-applicable}: ze reads no DHCP bytes itself -- the receive path is the vendored library's receiveLoop, which reads each datagram into a MaxMessageSize (1500 octet) buffer before decoding (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:256-271, MaxMessageSize at client.go:38), and ze only consumes the decoded result of client.RequestFromOffer and client.SendAndRead (nclient4Exchanger, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go); the RENEWING exchange's v4UnicastConn hands the device's raw-socket datagrams to that same receiveLoop
RFC2131-3.5-1 If the client includes a list of parameters in a DHCPDISCOVER message, it MUST include that list in any subsequent DHCPREQUEST messages. (§3.5) no test no test carries this requirement id; annotated {not-applicable}: the parameter request list is written by the vendored library, the same list in both messages -- NewDiscovery (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:198-209) and NewRequestFromOffer (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:256-270) each add the identical WithRequestedOptions set, and ze passes only hostname and client-id modifiers (internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4RequestModifiers), so it authors no request list
RFC2131-3.1-8 To help ensure that any BOOTP relay agents forward the DHCPREQUEST message to the same set of DHCP servers that received the original DHCPDISCOVER message, the DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP broadcast address as the original DHCPDISCOVER message. (§3.1) no test no test carries this requirement id; annotated {not-applicable}: the secs field and the broadcast flag of the SELECTING REQUEST are the vendored library's -- it leaves secs zero in both the DISCOVER and the REQUEST (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:164-180 sets no secs) and copies the flags word across with WithReply (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go:258, vendor/github.com/insomniacslk/dhcp/dhcpv4/modifiers.go:56-68), while ze's DORA call and its modifiers touch neither (internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go, nclient4Exchanger.acquire; internal/plugins/iface/dhcp/dhcp_v4_linux.go, v4RequestModifiers)
RFC2131-4.3.1-1 The configuration parameters MUST be selected by applying the following rules in the order given below. (§4.3.1) {gap}, no test ze applies no parameter-selection procedure -- buildReply emits one fixed option set in one fixed order (internal/plugins/dhcpserver/handler.go:245-285) and the parameter request list is never parsed (optParamReqList is defined at handler.go:52 and read nowhere in production), so the ordered rules of Section 4.3.1 govern no ze code path
RFC2131-4.3.1-3 -- IF the server recognizes the parameter as a parameter defined in the Host Requirements Document, the server MUST include the default value for that parameter as given in the Host Requirements Document in an appropriate option in the 'option' field, ELSE (§4.3.1) {gap}, no test ze returns only the values its own subnet configuration holds (buildReply internal/plugins/dhcpserver/handler.go:245-285); it reads no parameter request list (optParamReqList handler.go:52 is parsed nowhere in production) and carries no Host Requirements defaults, so a recognized parameter the client requests draws no default value
RFC2131-4.3.1-5 The server MUST supply as many of the requested parameters as possible and MUST omit any parameters it cannot provide. (§4.3.1) {gap}, no test the parameter request list is never parsed (optParamReqList internal/plugins/dhcpserver/handler.go:52 is read nowhere in production), so ze supplies its fixed configured option set (buildReply handler.go:245-285) rather than as many of the client's requested parameters as it can
RFC2131-4.3.1-7 o Any parameters specific to this client's class (as identified by the contents of the 'vendor class identifier' option in the DHCPDISCOVER or DHCPREQUEST message), e.g., as configured by the network administrator; the parameters MUST be identified by an exact match between the client's vendor class identifiers and the client's classes identified in the server, (§4.3.1) {gap}, no test ze identifies the vendor class by a ten-octet prefix comparison against the string PXEClient: (isPXEClient internal/plugins/dhcpserver/handler.go:493-496) rather than by an exact match against a configured class identifier, and that prefix match is what selects the class-specific options appended at handler.go:292-330
RFC2131-4.4.1-1 The client MUST include its hardware address in the 'chaddr' field, if necessary for delivery of DHCP reply messages. (§4.4.1) no test no test carries this requirement id; annotated {not-applicable}: chaddr is filled by the vendored library from the bound interface -- nclient4.New resolves the interface MAC (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:199-209) and NewDiscovery/NewRequestFromOffer set it with WithHwAddr (vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4packet.go); ze only names the kernel device to bind (nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go)
RFC2131-4.4.2-1 The client MUST insert its known network address as a 'requested IP address' option in the DHCPREQUEST message. (§4.4.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7
RFC2131-4.4.2-2 The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7
RFC2131-4.4.3-1 DHCPINFORM messages MUST be directed to the 'DHCP server' UDP port (§4.4.3) no test no test carries this requirement id; annotated {not-applicable}: ze's client sends no DHCPINFORM -- nclient4 exposes Inform (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go:483-498) and ze calls it nowhere; the exchanger uses only DiscoverOffer, RequestFromOffer and SendAndRead (nclient4Exchanger, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go)
RFC2131-3.2-3 As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. (§3.2) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client never enters INIT-REBOOT -- every acquisition is a full DORA (client.DiscoverOffer and client.RequestFromOffer in nclient4Exchanger.acquire, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and every lease extension is a RENEWING or REBINDING request built from the held ACK (dhcpv4.NewRenewFromAck in v4ExtendRequest, internal/plugins/iface/dhcp/dhcp_v4_linux.go); no ze code path caches an address to reboot with, so ze produces no INIT-REBOOT REQUEST
RFC2131-4.4-1 Vendor class identifier MAY MAY MUST NOT (§4.4) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7
RFC2131-4.4-2 Requested IP address MAY MUST (in MUST (DISCOVER) SELECTING or (DHCPDECLINE), (§4.4) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client sends no DHCPDECLINE, so no ze path builds the message whose fields this governs -- the lease loop installs the ACKed address directly (installV4Lease, internal/plugins/iface/dhcp/dhcp_v4_linux.go) and neither ze nor the vendored nclient4 client holds a DECLINE producer; that absence is itself recorded as the gap on RFC2131-3.1-7
RFC2131-4.4-3 Server identifier MUST NOT MUST (after MUST SELECTING) (§4.4) no test no test carries this requirement id; annotated {not-applicable}: ze's DHCPv4 client sends no DHCPRELEASE, so no ze path builds the message whose fields this governs -- the lease loop ends a lease by removing the address locally (teardownV4, internal/plugins/iface/dhcp/dhcp_v4_linux.go), and nclient4's Release (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go:26) is called nowhere in ze
RFC2131-4.1-16 DHCP messages broadcast by a client prior to that client obtaining its IP address must have the source address field in the IP header set to 0. (§4.1) no test no test carries this requirement id; annotated {not-applicable}: the IP header is written inside the vendored library -- ze's client opens its socket through nclient4.New (internal/plugins/iface/dhcp/dhcp_v4_linux.go), whose NewRawUDPConn binds a UDP address with no IP (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/conn_unix.go) and whose BroadcastRawUDPConn.WriteTo builds the IPv4 header from that bound address through udp4pkt; ze authors no IP header
RFC2131-4.4.1-4 If the 'xid' of an arriving DHCPOFFER message does not match the 'xid' of the most recent DHCPDISCOVER message, the DHCPOFFER message must be silently discarded. Any arriving DHCPACK messages must be silently discarded. (§4.4.1) no test no test carries this requirement id; annotated {not-applicable}: the SELECTING receive filter lives inside the vendored library -- nclient4's receiveLoop delivers a message only to the pending channel keyed by its TransactionID (vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go), and client.DiscoverOffer reads the DISCOVER answer through IsMessageType(dhcpv4.MessageTypeOffer), which skips any other type; ze calls only client.DiscoverOffer, client.RequestFromOffer and client.SendAndRead (nclient4Exchanger, internal/plugins/iface/dhcp/dhcp_v4_exchange_linux.go) and reads no reply bytes itself
RFC2131-4.3.1-10 The server must also choose an expiration time for the lease, as follows: (§4.3.1) {gap}, no test the first rule of the list is not followed -- a DHCPDISCOVER from a client that already holds a binding and requests no lease time is answered by handleDiscover through buildReply (internal/plugins/dhcpserver/handler.go), which writes the configured subnet LeaseTimeSec into option 51 rather than the expiration time previously assigned to that address, so every OFFER restarts the lease duration

Proof state

A tagged unit reads unproven where no discrimination record exists for it: nothing in this tree has been observed to break it, so the claim its tag makes is unproven.

RFC2131-4.3-1

Server identifier MUST MUST MUST (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. single-polarity positive: option 54 in OFFER, ACK and NAK must equal the server address, so omitting or mis-setting it goes red

PolarityTestKind and tierProof state
positive TestServerIdentifierInEveryReply unit/verify unproven

RFC2131-4.3-2

IP address lease time MUST (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. single-polarity positive: the OFFER's option 51 must be four octets equal to the configured lease seconds

PolarityTestKind and tierProof state
positive TestLeaseTimeInOfferAndAck unit/verify unproven

RFC2131-4.3-3

IP address lease time MUST MUST (DHCPREQUEST) (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. single-polarity positive: the ACK answering a DHCPREQUEST must carry option 51 equal to the configured lease seconds

PolarityTestKind and tierProof state
positive TestLeaseTimeInOfferAndAck unit/verify unproven

RFC2131-4.3-4

IP address lease time MUST MUST (DHCPREQUEST) MUST NOT (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: the NAK's option walk holds no 51; negative: a REQUEST carrying option 51 that is NAKed still yields a NAK without 51

PolarityTestKind and tierProof state
negative TestReplyDoesNotEchoClientOptions unit/verify unproven
positive TestReplyOmitsClientOnlyOptions unit/verify unproven

RFC2131-4.3-5

Requested IP address MUST NOT MUST NOT MUST NOT (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: no OFFER/ACK/NAK carries option 50; negative: requests carrying option 50 still draw OFFER/ACK/NAK without it

PolarityTestKind and tierProof state
negative TestReplyDoesNotEchoClientOptions unit/verify unproven
positive TestReplyOmitsClientOnlyOptions unit/verify unproven

RFC2131-4.3-6

Client identifier MUST NOT MUST NOT (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: neither OFFER nor ACK carries option 61; negative: requests carrying option 61 still draw OFFER/ACK without it. The NAK column (MAY) is correctly left unasserted

PolarityTestKind and tierProof state
negative TestReplyDoesNotEchoClientOptions unit/verify unproven
positive TestReplyOmitsClientOnlyOptions unit/verify unproven

RFC2131-4.3-7

Parameter request list MUST NOT MUST NOT MUST NOT (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: no OFFER/ACK/NAK carries option 55; negative: requests carrying option 55 still draw replies without it

PolarityTestKind and tierProof state
negative TestReplyDoesNotEchoClientOptions unit/verify unproven
positive TestReplyOmitsClientOnlyOptions unit/verify unproven

RFC2131-4.3-8

Maximum message size MUST NOT MUST NOT MUST NOT (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: no OFFER/ACK/NAK carries option 57; negative: requests carrying option 57 still draw replies without it

PolarityTestKind and tierProof state
negative TestReplyDoesNotEchoClientOptions unit/verify unproven
positive TestReplyOmitsClientOnlyOptions unit/verify unproven

RFC2131-4.3-9

All others MAY MAY MUST NOT (§4.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive and negative both require every NAK option code to be 53 or 54, so any option Table 3 marks 'All others' goes red. The assertion is stricter than Table 3: it would also go red on the Message option (56, SHOULD), Client identifier (61, MAY) and Vendor class identifier (60, MAY), which Table 3 allows in a DHCPNAK

PolarityTestKind and tierProof state
negative TestReplyDoesNotEchoClientOptions unit/verify unproven
positive TestReplyOmitsClientOnlyOptions unit/verify unproven

RFC2131-4.3.5-1

The server MUST NOT send a lease expiration time to the client (§4.3.5)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.5-1, so no unit is bound to it.

RFC2131-4.3.2-1

If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on the same subnet as the server. The server MUST broadcast the DHCPNAK message to the 0xffffffff broadcast address (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.2-1, so no unit is bound to it.

RFC2131-4.3.2-2

If 'giaddr' is set in the DHCPREQUEST message, the client is on a different subnet. The server MUST set the broadcast bit in the DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the client (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.2-2, so no unit is bound to it.

RFC2131-3.2-4

Otherwise, the server MUST send the DHCPNAK message to the IP address of the BOOTP relay agent, as recorded in 'giaddr'. (§3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive relays a SELECTING REQUEST with giaddr 192.168.1.254 and asserts responseAddr gives 192.168.1.254:67 for the resulting NAK; negative asserts the same NAK with giaddr zero goes to 255.255.255.255:68, not to a relay

PolarityTestKind and tierProof state
negative TestNakDeliveredToRelayAgent unit/verify revert, verified
positive TestNakDeliveredToRelayAgent unit/verify revert, verified

RFC2131-4.3.2-3

If the DHCP server has no record of this client, then it MUST remain silent (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.2-3, so no unit is bound to it.

RFC2131-4.3.3-1

The server MUST mark the network address as not available (§4.3.3)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.3-1, so no unit is bound to it.

RFC2131-4.1-1

A server with multiple network addresses MUST be prepared to to accept any of its network addresses as identifying that server in a DHCP message. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-1, so no unit is bound to it.

RFC2131-4.1-2

To accommodate potentially incomplete network connectivity, a server MUST choose an address as a 'server identifier' that, to the best of the server's knowledge, is reachable from the client. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-2, so no unit is bound to it.

RFC2131-4.2-1

If the client supplies a 'client identifier', the client MUST use the same 'client identifier' in all subsequent messages, and the server MUST use that identifier to identify the client. (§4.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.2-1, so no unit is bound to it.

RFC2131-4.2-2

If the client does not provide a 'client identifier' option, the server MUST use the contents of the 'chaddr' field to identify the client. (§4.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-18 (independent auditor, after ef8666639d). RFC 2131 Section 4.2: "If the client does not provide a 'client identifier' option, the server MUST use the contents of the 'chaddr' field to identify the client." ef8666639d only deletes the stale comment line above TestRFC2131ChaddrContentsIdentifyTheClient that the previous verdict asked removed; no assertion changed. The server reads no option 61 and handle keys every message type on extractMAC (pkt[28:28+hlen]). Overlay mutants on handler.go extractMAC, run under ./le job run: keying on xid reds TestRFC2131ChaddrContentsIdentifyTheClient and TestChaddrIdentifiesClientWithoutClientIdentifier; keying on all but the last chaddr octet reds TestRFC2131ChaddrContentsIdentifyTheClient. Positive (same chaddr, different xid and flags, one client) and negative (one chaddr octet differs, two clients) are distinct assertions.

PolarityTestKind and tierProof state
negative TestRFC2131ChaddrContentsIdentifyTheClient unit/verify revert, verified
positive TestRFC2131ChaddrContentsIdentifyTheClient unit/verify revert, verified
positive TestChaddrIdentifiesClientWithoutClientIdentifier unit/verify revert, verified

RFC2131-2-1

The 'client identifier' chosen by a DHCP client MUST be unique to that client within the subnet to which the client is attached. (§2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-2-1, so no unit is bound to it.

RFC2131-2-2

If the client uses a 'client identifier' in one message, it MUST use that same identifier in all subsequent messages, to ensure that all servers correctly identify the client. (§2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExtendIgnoresServerEchoesOnVeth unit/verify revert, verified
positive TestDHCPv4RenewCarriesClientID unit/verify revert, verified

RFC2131-3.1-1

The client broadcasts a DHCPREQUEST message that MUST include the 'server identifier' option to indicate which server it has selected (§3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-1, so no unit is bound to it.

RFC2131-3.1-2

The 'requested IP address' option MUST be set to the value of 'yiaddr' in the DHCPOFFER message from the server. (§3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-2, so no unit is bound to it.

RFC2131-3.1-3

'requested IP address' option MUST be filled in with client's notion of its previously assigned address. (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-3, so no unit is bound to it.

RFC2131-3.1-4

DHCPREQUEST generated during INIT-REBOOT state: 'server identifier' MUST NOT be filled in (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-4, so no unit is bound to it.

RFC2131-3.1-5

'server identifier' MUST NOT be filled in, 'requested IP address' option MUST NOT be filled in (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExtendIgnoresServerEchoesOnVeth unit/verify revert, verified
positive TestDHCPv4RebindAcceptsAnyServerOnVeth unit/verify revert, verified

RFC2131-3.2-1

As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. (§3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.2-1, so no unit is bound to it.

RFC2131-3.1-6

If the client used a 'client identifier' when it obtained the lease, it MUST use the same 'client identifier' in the DHCPRELEASE message. (§3.1, §3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-6, so no unit is bound to it.

RFC2131-3.1-7

If the client detects that the address is already in use (e.g., through the use of ARP), the client MUST send a DHCPDECLINE message to the server and restarts the configuration process. (§3.1, §3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-7, so no unit is bound to it.

RFC2131-4.4.5-1

If the lease expires before the client receives a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requests network initialization parameters as if the client were uninitialized. (§4.4.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExpiresOnTimeOnVeth unit/verify revert, verified
positive TestDHCPv4RenewsRepeatedlyOnVeth unit/verify revert, verified

RFC2131-3-1

The first four octets of the 'options' field of the DHCP message contain the (decimal) values 99, 130, 83 and 99, respectively (§3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive reads octets 236..239 of OFFER, ACK and NAK and pins 0x63825363; negative replaces the cookie with 0xDEADBEEF and asserts h.handle returns nil

PolarityTestKind and tierProof state
negative TestMagicCookieRequiredAndEmitted unit/verify unproven
positive TestMagicCookieRequiredAndEmitted unit/verify unproven

RFC2131-4.1-3

The last option must always be the 'end' option. (§4.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive walks each OFFER/ACK/NAK option by its length octets and requires reaching End (255); negative fills a request's options with 0x01 so it carries no End, and requires the reply to be End-terminated

PolarityTestKind and tierProof state
negative TestReplyOptionsTerminatedByEnd unit/verify unproven
positive TestReplyOptionsTerminatedByEnd unit/verify unproven

RFC2131-4.1-4

If the options in a DHCP message extend into the 'sname' and 'file' fields, the 'option overload' option MUST appear in the 'options' field, with value 1, 2 or 3, as specified in RFC 1533. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-4, so no unit is bound to it.

RFC2131-4.1-5

The options in the 'sname' and 'file' fields (if in use as indicated by the 'options overload' option) MUST begin with the first octet of the field, MUST be terminated by an 'end' option, and MUST be followed by 'pad' options to fill the remainder of the field. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-5, so no unit is bound to it.

RFC2131-4.1-6

Any individual option in the 'options', 'sname' and 'file' fields MUST be entirely contained in that field. (§4.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: TestRFC2131EveryReplyOptionContainedInItsField walks OFFER, ACK and the separately built DHCPNAK by length octets to End inside the options field and requires sname/file all zero with no option 52; TestOptionsContainedWithinTheirField keeps the OFFER/ACK walk. negative: a 300-octet bootfile; judge overlay removing the 255 guard in safeAppendOption reddens it ('option code 98 at offset 555 declares length 98, overrunning the options field'). Receiver side: TestOptionsContainedWithinTheirField negative, an overrunning received option is not read past the field. Config refuses bootfile-bios/uefi over 255 (TestParsePXEConfigInvalid)

PolarityTestKind and tierProof state
negative TestRFC2131EveryReplyOptionContainedInItsField unit/verify revert, verified
negative TestOptionsContainedWithinTheirField unit/verify revert, verified
positive TestRFC2131EveryReplyOptionContainedInItsField unit/verify revert, verified
positive TestOptionsContainedWithinTheirField unit/verify revert, verified

RFC2131-4.1-7

The options in the 'options' field MUST be interpreted first, so that any 'option overload' options may be interpreted. (§4.1)

Audit verdict: enforced (the tests do what the requirement demands), stale-unit: internal/plugins/dhcpserver/options.go::findOption moved. Re-judged 2026-10-18 (independent auditor, after ef8666639d). RFC 2131 Section 4.1: "The options in the 'options' field MUST be interpreted first, so that any 'option overload' options may be interpreted. The 'file' field MUST be interpreted next (if the 'option overload' option indicates that the 'file' field contains DHCP options), followed by the 'sname' field." findOption walks pkt[240:] first and overloadValue reads option 52 from the options field only; parseMsgType and parseOptionAddr, and h.handle through them, go through findOption. ef8666639d tags the options-first assertion of TestOverloadInterpretationOrder (options, file and sname each carry option 50 under 52=3; the options copy must win) as positive, so the order clause now has a tagged, discriminating assertion beside TestOverloadFieldsCarryOptions (52 interpreted: 53 and 50 in file/sname under 1/2/3 draw a DHCPACK). Negative unchanged: a 52 planted inside file opens no sname. Overlay mutants on options.go, run under ./le job run: walking file before options reds the newly tagged line 131; ignoring 52 reds TestOverloadFieldsCarryOptions (file, sname, both); honouring a 52 found inside file reds the negative at line 150. Recorded breaks are whole-body panics proving reach; these mutants supply the deciding-logic proof. Claims are no wider than the assertions.

PolarityTestKind and tierProof state
negative TestOverloadInterpretationOrder unit/verify revert, verified
positive TestOverloadFieldsCarryOptions unit/verify revert, producer-changed (the producer's behavior changed since the break was applied to it)
positive TestOverloadInterpretationOrder unit/verify revert, producer-changed (the producer's behavior changed since the break was applied to it)

RFC2131-4.1-15

The 'file' field MUST be interpreted next (if the 'option overload' option indicates that the 'file' field contains DHCP options), followed by the 'sname' field. (§4.1)

Audit verdict: enforced (the tests do what the requirement demands), stale-unit: internal/plugins/dhcpserver/options.go::findOption moved. Re-judged 2026-10-18 (independent auditor, after ef8666639d). RFC 2131 Section 4.1: "The options in the 'options' field MUST be interpreted first, so that any 'option overload' options may be interpreted. The 'file' field MUST be interpreted next (if the 'option overload' option indicates that the 'file' field contains DHCP options), followed by the 'sname' field." RFC 2132 Section 9.3 values: 1 file, 2 sname, 3 both. findOption reads file only under 52 = 1 or 3, then sname only under 2 or 3. The survivor named by the previous verdict is now killed: ef8666639d adds to TestOverloadAbsentFieldsIgnored a 52=2 packet whose requested address sits in file, asserting it is not read and the request draws a DHCPNAK (tagged negative). Overlay mutants, run under ./le job run: reading file under 52=2 reds that new case (line 197, and the reply turns DHCPACK instead of DHCPNAK at line 204); ignoring 52 reds the positives (TestOverloadFieldsCarryOptions file/sname/both, and line 139); walking sname before file reds TestOverloadInterpretationOrder at line 139 (file copy must win under 52=3). Each field's opening condition and the file-then-sname order are now discriminated in both polarities: 52 absent leaves both unread, 1 leaves sname unread, 2 leaves file unread. Units changed, so this is a fresh judgement, not an upgrade over unchanged units.

PolarityTestKind and tierProof state
negative TestOverloadAbsentFieldsIgnored unit/verify revert, producer-changed (the producer's behavior changed since the break was applied to it)
positive TestOverloadFieldsCarryOptions unit/verify revert, producer-changed (the producer's behavior changed since the break was applied to it)
positive TestOverloadInterpretationOrder unit/verify revert, producer-changed (the producer's behavior changed since the break was applied to it)

RFC2131-4.1-8

The client MUST adopt a retransmission strategy that incorporates a randomized exponential backoff algorithm to determine the delay between retransmissions. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-8, so no unit is bound to it.

RFC2131-4.1-9

A DHCP client MUST choose 'xid's in such a way as to minimize the chance of using an 'xid' identical to one used by another client. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-9, so no unit is bound to it.

RFC2131-4.1-10

DHCP clients MUST use the IP address provided in the 'server identifier' option for any unicast requests to the DHCP server. (§4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExtendIgnoresServerEchoesOnVeth unit/verify revert, verified
positive TestDHCPv4RenewIsUnicastToServer unit/verify revert, verified

RFC2131-3.4-1

The server SHOULD check the network address in a DHCPINFORM message for consistency, but MUST NOT check for an existing lease. (§3.4)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.4-1, so no unit is bound to it.

RFC2131-2-3

The remaining bits of the flags field are reserved for future use. They MUST be set to zero by clients and ignored by servers and relay agents. (§2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Every clause, both producer paths. Server: TestFlagsReservedBitsIgnored sends flags 0 (positive) and 0x7fff (negative) and asserts the reply is unicast to yiaddr:68 either way, so bits 1-15 are ignored; recorded against dhcpserver responseAddr (revert, both polarities). Client acquisition: TestRFC2131ClientSetsReservedFlagsBitsToZero (guest, real client over veth) reads the DISCOVER (positive) and, after an OFFER with flags 0xffff, the REQUEST (negative, bits 1-15 zero); recorded against clearReservedFlags. Client renewal: TestRFC2131ClientRenewalSetsReservedFlagsBitsToZero binds a lease from an ACK with flags 0xffff and a 2 s lease, reads the T1 renewing REQUEST (identified by ciaddr, since NewRenewFromAck copies the ACK xid) and asserts bits 1-15 zero; re-judged 2026-10-18 after renewV4 was replaced by the lease-maintenance loop: the renewing and rebinding REQUESTs are built by v4ExtendRequest, which applies v4RequestModifiers and so clearReservedFlags after NewRenewFromAck, and the record is against v4ExtendRequest (revert). v4ExtendRequest and the acquisition Request are the only client send paths (no release/decline/inform). Records are panic reverts.

PolarityTestKind and tierProof state
negative TestFlagsReservedBitsIgnored unit/verify revert, verified
negative TestRFC2131ClientRenewalSetsReservedFlagsBitsToZero unit/verify revert, verified
negative TestRFC2131ClientSetsReservedFlagsBitsToZero unit/verify revert, verified
positive TestFlagsReservedBitsIgnored unit/verify revert, verified
positive TestRFC2131ClientSetsReservedFlagsBitsToZero unit/verify revert, verified

RFC2131-2-4

A DHCP client must be prepared to receive DHCP messages with an 'options' field of at least length 312 octets. (§2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-2-4, so no unit is bound to it.

RFC2131-3.5-1

If the client includes a list of parameters in a DHCPDISCOVER message, it MUST include that list in any subsequent DHCPREQUEST messages. (§3.5)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.5-1, so no unit is bound to it.

RFC2131-4.4.5-2

T1 MUST be earlier than T2 (§4.4.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestShortLeaseTimeRejected unit/verify unproven
negative TestV4ServerTimersHonoredWhenOrdered unit/verify revert, verified
positive TestRenewalTimersOrderedWithinLease unit/verify unproven
positive TestV4ServerTimersHonoredWhenOrdered unit/verify revert, verified

RFC2131-4.4.5-3

T2, which, in turn, MUST be earlier than the time at which the client's lease will expire. (§4.4.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Server: for leases 60, 3600, 86400 and 604800 the OFFER's option 59 (T2) must be strictly below the lease seconds (positive); parseConfig must reject lease-time 0 (negative). Client, re-judged 2026-10-19 after the DHCPv4 lease loop: TestV4ServerTimersHonoredWhenOrdered calls v4LeaseTimers, the only producer of the client's T2, and asserts a server T2 below the lease (99 s and 95 s in 100 s) is used (positive) and a T2 at the lease (100 s) falls back to both defaults (negative); the default T2 is lease - lease/8 (v4RenewalTimes), below any finite lease. Revert records for both polarities.

PolarityTestKind and tierProof state
negative TestShortLeaseTimeRejected unit/verify unproven
negative TestV4ServerTimersHonoredWhenOrdered unit/verify revert, verified
positive TestRenewalTimersOrderedWithinLease unit/verify unproven
positive TestV4ServerTimersHonoredWhenOrdered unit/verify revert, verified

RFC2131-3.1-8

To help ensure that any BOOTP relay agents forward the DHCPREQUEST message to the same set of DHCP servers that received the original DHCPDISCOVER message, the DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP broadcast address as the original DHCPDISCOVER message. (§3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.1-8, so no unit is bound to it.

RFC2131-4.3.1-1

The configuration parameters MUST be selected by applying the following rules in the order given below. (§4.3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.1-1, so no unit is bound to it.

RFC2131-4.3.1-2

-- IF the server has been explicitly configured with a default value for the parameter, the server MUST include that value in an appropriate option in the 'option' field, ELSE (§4.3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. positive: requested subnet mask, router, DNS and domain name each equal the configured bytes exactly (DNS now byte for byte, closing the length-only gap); negative: a request suggesting other values for all four still gets the configured ones, so a server echoing client-suggested values goes red. {single-polarity} correctly removed from the row

PolarityTestKind and tierProof state
negative TestRFC2131ConfiguredParameterValuesReturned unit/verify revert, verified
positive TestRFC2131ConfiguredParameterValuesReturned unit/verify revert, verified
positive TestUnconfiguredParametersOmitted unit/verify revert, verified

RFC2131-4.3.1-3

-- IF the server recognizes the parameter as a parameter defined in the Host Requirements Document, the server MUST include the default value for that parameter as given in the Host Requirements Document in an appropriate option in the 'option' field, ELSE (§4.3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.1-3, so no unit is bound to it.

RFC2131-4.3.1-4

The server MUST NOT return a value for that parameter, (§4.3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: returning a value for a parameter the server has no value for (neither configured nor a Host Requirements default). TestUnconfiguredParametersOmitted builds a handler with no router, DNS or domain name configured; the negative tag sends a DISCOVER whose parameter request list explicitly names optRouter, optDNS and optDomainName and asserts askedCodes[code] is false for each, so any emitted option for them (including an empty or zero-valued one, since replyOptionCodes records presence by code) goes red. The positive tag asserts the same absence for an unrequested DISCOVER. None of the three has a Host Requirements default, so the ELSE branch applies.

PolarityTestKind and tierProof state
negative TestUnconfiguredParametersOmitted unit/verify unproven
positive TestUnconfiguredParametersOmitted unit/verify unproven

RFC2131-4.3.1-5

The server MUST supply as many of the requested parameters as possible and MUST omit any parameters it cannot provide. (§4.3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.1-5, so no unit is bound to it.

RFC2131-4.3.1-6

The server MUST include each requested parameter only once unless explicitly allowed in the DHCP Options and BOOTP Vendor Extensions document. (§4.3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: a requested parameter included more than once in a reply (no option ze emits is one the options document allows to repeat). TestEachParameterEmittedOnce counts every option code in the OFFER and ACK with replyOptionCounts and fails on n != 1 (positive); the negative tag sends a DISCOVER whose parameter request list repeats router, DNS and subnet mask, carries a second PRL and an echoed router option, to both a plain and a PXE server, and fails on any option count other than 1, so a duplicated parameter goes red.

PolarityTestKind and tierProof state
negative TestEachParameterEmittedOnce unit/verify unproven
positive TestEachParameterEmittedOnce unit/verify unproven

RFC2131-4.3.1-7

o Any parameters specific to this client's class (as identified by the contents of the 'vendor class identifier' option in the DHCPDISCOVER or DHCPREQUEST message), e.g., as configured by the network administrator; the parameters MUST be identified by an exact match between the client's vendor class identifiers and the client's classes identified in the server, (§4.3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.1-7, so no unit is bound to it.

RFC2131-4.4.1-1

The client MUST include its hardware address in the 'chaddr' field, if necessary for delivery of DHCP reply messages. (§4.4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4.1-1, so no unit is bound to it.

RFC2131-4.4.2-1

The client MUST insert its known network address as a 'requested IP address' option in the DHCPREQUEST message. (§4.4.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4.2-1, so no unit is bound to it.

RFC2131-4.4.2-2

The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4.2-2, so no unit is bound to it.

RFC2131-4.4.3-1

DHCPINFORM messages MUST be directed to the 'DHCP server' UDP port (§4.4.3)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4.3-1, so no unit is bound to it.

RFC2131-4.3.2-5

This message MUST be broadcast to the 0xffffffff IP broadcast address. (§4.3.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExtendIgnoresServerEchoesOnVeth unit/verify revert, verified
positive TestDHCPv4RebindAcceptsAnyServerOnVeth unit/verify revert, verified

RFC2131-4.4.5-5

If the client is given a new network address, it MUST NOT continue using the previous network address (§4.4.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4RenewsRepeatedlyOnVeth unit/verify revert, verified
positive TestDHCPv4RenewalMovesToNewAddressOnVeth unit/verify revert, verified

RFC2131-4.4.5-6

The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExtendIgnoresServerEchoesOnVeth unit/verify revert, verified
positive TestDHCPv4RenewIsUnicastToServer unit/verify revert, verified

RFC2131-4.4.5-7

The client MUST NOT include a 'server identifier' in the DHCPREQUEST message. (§4.4.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDHCPv4ExtendIgnoresServerEchoesOnVeth unit/verify revert, verified
positive TestDHCPv4RebindAcceptsAnyServerOnVeth unit/verify revert, verified

RFC2131-3.2-3

As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. (§3.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-3.2-3, so no unit is bound to it.

RFC2131-4.4-1

Vendor class identifier MAY MAY MUST NOT (§4.4)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4-1, so no unit is bound to it.

RFC2131-4.4-2

Requested IP address MAY MUST (in MUST (DISCOVER) SELECTING or (DHCPDECLINE), (§4.4)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4-2, so no unit is bound to it.

RFC2131-4.4-3

Server identifier MUST NOT MUST (after MUST SELECTING) (§4.4)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4-3, so no unit is bound to it.

RFC2131-4.4.5-8

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. (§4.4.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestV4RetransmitSchedule unit/verify revert, verified
positive TestV4RetransmitSchedule unit/verify revert, verified

RFC2131-3-2

One particular option - the "DHCP message type" option - must be included in every DHCP message. (§3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestMessageTypeInEveryReply unit/verify revert, verified

RFC2131-3.6-1

A client with multiple network interfaces must use DHCP through each interface independently to obtain configuration information parameters for those separate interfaces. (§3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestRFC2131ClientRunsDHCPOnEachInterfaceIndependently unit/verify revert, verified

RFC2131-4.1-16

DHCP messages broadcast by a client prior to that client obtaining its IP address must have the source address field in the IP header set to 0. (§4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.1-16, so no unit is bound to it.

RFC2131-4.4.1-4

If the 'xid' of an arriving DHCPOFFER message does not match the 'xid' of the most recent DHCPDISCOVER message, the DHCPOFFER message must be silently discarded. Any arriving DHCPACK messages must be silently discarded. (§4.4.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.4.1-4, so no unit is bound to it.

RFC2131-4.3.1-10

The server must also choose an expiration time for the lease, as follows: (§4.3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC2131-4.3.1-10, so no unit is bound to it.

Extraction sign-off

FieldValue
Reviewer claude
Signed off 2026-09-29
Register prose
Source rfc/full/rfc2131.txt
Source fingerprint 034052024822fc6a
Record rfc/extraction/rfc2131.json
Mapped sentences 59
Declined as scope 31
Relocated to a spec, which Ze OWES 0
Unclassified 0

Sections

SectionNameSitesDispositionReason
front not stated 0 walked not stated
1 not stated 0 walked not stated
1.1 not stated 0 walked not stated
1.2 not stated 0 walked not stated
1.3 not stated 2 walked not stated
1.4 not stated 3 walked not stated
1.5 not stated 0 walked not stated
1.6 not stated 7 walked not stated
2 not stated 6 walked not stated
2.1 not stated 0 walked not stated
2.2 not stated 0 walked not stated
3 not stated 2 walked not stated
3.1 not stated 5 walked not stated
3.2 not stated 6 walked not stated
3.3 not stated 0 walked not stated
3.4 not stated 1 walked not stated
3.5 not stated 2 walked not stated
3.6 not stated 1 walked not stated
3.7 not stated 1 walked not stated
4 not stated 0 walked not stated
4.1 not stated 13 walked not stated
4.2 not stated 3 walked not stated
4.3 not stated 0 walked not stated
4.3.1 not stated 10 walked not stated
4.3.2 not stated 10 walked not stated
4.3.3 not stated 1 walked not stated
4.3.4 not stated 0 walked not stated
4.3.5 not stated 1 walked not stated
4.3.6 not stated 1 walked not stated
4.4 not stated 0 walked not stated
4.4.1 not stated 7 walked not stated
4.4.2 not stated 2 walked not stated
4.4.3 not stated 1 walked not stated
4.4.4 not stated 0 walked not stated
4.4.5 not stated 5 walked not stated
4.4.6 not stated 0 walked not stated
5 not stated 0 walked not stated
6 not stated 0 walked not stated
7 not stated 0 walked not stated
8 not stated 0 walked not stated
A not stated 0 walked not stated

Excluded sentences

SiteExcluded kindReasonQuote
1.3:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.3 describes which parameters a newly initialized client needs; the lowercase 'required' states a fact and directs no implementation Not all of these parameters are required for a newly initialized client.
1.3:2 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
a permission ('may negotiate') reached only through the lowercase 'required'; it directs no behavior A client and server may negotiate for the transmission of only those parameters required by the client or specific to a particular subnet.
1.4:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
the bullet heading of the RFC 2119 keyword glossary, quoting the word itself rather than stating an obligation o "MUST"
1.4:2 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
RFC 2119 boilerplate defining what the word MUST means in this document This word or the adjective "REQUIRED" means that the item is an absolute requirement of this specification.
1.4:3 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
the bullet heading of the RFC 2119 keyword glossary, quoting the words MUST NOT rather than stating an obligation o "MUST NOT"
1.6:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.6 introduces this list as 'general design goals for DHCP'; the lowercase must states a goal of the protocol design that sections 3 and 4 turn into obligations, and directs no implementation by itself DHCP must allow local system administrators control over configuration parameters where desired; e.g., local system administrators should be able to enforce local policies concerning allocation and access to local resources where desired. o Clients should require no manual configuration.
1.6:2 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.6 introduces this list as 'general design goals for DHCP'; working across routers is a goal the relay rules of sections 4.1 and 4.3 realize, and the sentence directs no implementation by itself To allow for scale and economy, DHCP must work across routers or through the intervention of BOOTP relay agents.
1.6:3 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.6 introduces this list as 'general design goals for DHCP'; the client's handling of several DHCPOFFERs is specified in sections 3.1 and 4.4.1, and this goal directs no implementation by itself o A DHCP client must be prepared to receive multiple responses to a request for configuration parameters.
1.6:4 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.6 introduces this list as 'general design goals for DHCP'; coexistence with static hosts is a design goal and directs no implementation o DHCP must coexist with statically configured, non-participating hosts and with existing network protocol implementations.
1.6:5 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.6 introduces this list as 'general design goals for DHCP'; relay interoperation is a design goal whose obligations belong to RFC 951 and RFC 1542 and to the section 4 relay rules o DHCP must interoperate with the BOOTP relay agent behavior as described by RFC 951 and by RFC 1542 [21].
1.6:6 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
section 1.6 introduces this list as 'general design goals for DHCP'; BOOTP client service is a design goal whose obligations are in section 4 and RFC 1534 o DHCP must provide service to existing BOOTP clients.
1.6:7 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
the lead-in 'DHCP must:' to the section 1.6 list of 'design goals specific to the transmission of the network layer parameters'; it states protocol design goals and directs no implementation DHCP must:
2:4 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
the sentence opens 'This requirement implies' and restates the 312-octet options obligation as a 576-octet message; site 2:3 maps it This requirement implies that a DHCP client must be prepared to receive a message of up to 576 octets, the minimum IP datagram size an IP host must be prepared to accept [3].
2:6 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
the figure legend for the 'flags' field restates the same obligation as the section 2 sentence 'They MUST be set to zero by clients and ignored by servers and relay agents' MBZ: MUST BE ZERO (reserved for future use)
3:2 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
the sentence points at the per-message option tables of sections 4.3.1 and 4.4.1, whose rows RFC2131-4.3-1 to 4.3-9 and RFC2131-4.4-1 to 4.4-3 carry the obligations; it states none of its own Additional options may be allowed, required, or not allowed, depending on the DHCP message type.
3.2:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 3.2 restates for the INIT-REBOOT DHCPREQUEST the section 2 obligation that a client which uses a 'client identifier' in one message uses that same identifier in all subsequent messages If the client used a 'client identifier' to obtain its address, the client MUST use the same 'client identifier' in the DHCPREQUEST message.
3.2:3 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 3.2 and section 4.3.2 carry the same sentence word for word; site 4.3.2:6 maps it The server MUST broadcast the DHCPNAK message to the 0xffffffff broadcast address because the client may not have a correct network address or subnet mask, and the client may not be answering ARP requests.
3.2:5 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 3.2 restates the section 3.1 obligation to send a DHCPDECLINE when the client detects the assigned address is already in use; site 3.1:4 maps it If the client detects that the IP address in the DHCPACK message is already in use, the client MUST send a DHCPDECLINE message to the server and restarts the configuration process by requesting a new network address.
3.2:6 feature-out-of-scope
never bound Ze
the RFC makes a feature OPTIONAL, Ze decided not to offer it, and this obligation is conditional on offering it
section 3.2 makes reuse of a remembered address optional: "If a client remembers and wishes to reuse a previously allocated network address, a client may choose to omit some of the steps described in the previous section." ze's DHCPv4 client never enters INIT-REBOOT (every acquisition is a full DORA through client.Request in internal/plugins/iface/dhcp/dhcp_v4_linux.go), so it never holds the remembered address this DHCPNAK rule withdraws; the Support remaining row discloses the absent state It must instead request a new address by restarting the configuration process, this time using the (non-abbreviated) procedure described in section 3.1.
3.5:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
the parenthetical places the option overload flags in the 'options' field, which section 4.1 states as the 'option overload' option appearing in the 'options' field; site 4.1:6 maps it In this case, two additional options flags (which must appear in the 'options' field of the message) indicate that the 'file' and 'sname' fields are to be used for options.
3.7:1 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 3.7 restates for a client that cannot reach a server the section 4.4.5 obligation that a client whose lease expires with no DHCPACK stops using the address at once; site 4.4.5:4 maps it If the lease expires before the client can contact a DHCP server, the client must immediately discontinue use of the previous network address and may inform local users of the problem.
4.2:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
'DHCP servers are not required to respond' grants a server discretion and directs no behavior DHCP servers are not required to respond to every DHCPDISCOVER and DHCPREQUEST message they receive.
4.3.1:5 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
'The server MUST return to the client:' is the lead-in to the ordered selection rules the previous sentence already binds; site 4.3.1:4 maps it The server MUST return to the client:
4.3.2:1 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 4.3.2 restates the section 2 'same client identifier in all subsequent messages' obligation; site 2:2 maps it If the client uses a 'client identifier' in a DHCPREQUEST message, it MUST use that same 'client identifier' in all subsequent messages.
4.3.2:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 4.3.2 restates the section 3.5 obligation to carry the requested-parameter list into subsequent messages; site 3.5:1 maps it If the client included a list of requested parameters in a DHCPDISCOVER message, it MUST include that list in all subsequent messages.
4.3.2:3 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
the SELECTING row of the section 4.3.2 field list restates Table 4, whose SELECTING obligations RFC2131-3.1-1 and RFC2131-3.1-2 already carry, and whose 'ciaddr MUST be zero' clause RFC2131-3.2-1 carries Client inserts the address of the selected server in 'server identifier', 'ciaddr' MUST be zero, 'requested IP address' MUST be filled in with the yiaddr value from the chosen DHCPOFFER.
4.3.2:9 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
the REBINDING row repeats the RENEWING row word for word; site 4.3.2:8 maps it 'server identifier' MUST NOT be filled in, 'requested IP address' option MUST NOT be filled in, 'ciaddr' MUST be filled in with client's IP address.
4.3.6:1 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
Table 4 itself, whose per-state obligations RFC2131-3.1-1 through RFC2131-3.1-5 already carry --------------------------------------------------------------------- | |INIT-REBOOT |SELECTING |RENEWING |REBINDING | --------------------------------------------------------------------- |broad/unicast |broadcast |broadcast |unicast |broadcast | |server-ip |MUST NOT |MUST |MUST NOT |MUST NOT | |requested-ip |MUST |MUST |MUST NOT |MUST NOT | |ciaddr |zero |zero |IP address |IP address| ---------------------------------------------------------------------
4.4.1:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 4.4.1 restates the section 3.5 obligation to carry the requested-parameter list into subsequent messages; site 3.5:1 maps it If the client included a list of requested parameters in a DHCPDISCOVER message, it MUST include that list in all subsequent messages.
4.4.1:6 feature-out-of-scope
never bound Ze
the RFC makes a feature OPTIONAL, Ze decided not to offer it, and this obligation is conditional on offering it
section 4.4.1 makes the ARP request optional: "if the client is on a network that supports ARP, the client may issue an ARP request for the suggested request." ze's client issues none (handleV4Lease in internal/plugins/iface/dhcp/dhcp_v4_linux.go installs the ACKed address directly), so the rule for the ARP request's sender fields governs no code path; the Support remaining row discloses the absent probe 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.
4.4.1:7 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
section 4.4.1 restates the section 3.1 obligation to send a DHCPDECLINE when the address appears to be in use; site 3.1:4 maps it If the network address appears to be in use, the client MUST send a DHCPDECLINE message to the server.

Superseded

No document obsoletes RFC 2131, so its obligations are stated where they were written.