diff --git a/core/internal/network/dhcp/dhcp.go b/core/internal/network/dhcp/dhcp.go
index 6621f1e..9a62c7c 100644
--- a/core/internal/network/dhcp/dhcp.go
+++ b/core/internal/network/dhcp/dhcp.go
@@ -84,13 +84,13 @@
 
 		err = supervisor.Run(ctx, "client", func(ctx context.Context) error {
 			supervisor.Signal(ctx, supervisor.SignalHealthy)
-			_, ack, err := client.Request(ctx)
+			lease, err := client.Request(ctx)
 			if err != nil {
 				// TODO(q3k): implement retry logic with full state machine
 				logger.Errorf("DHCP lease request failed: %v", err)
 				return err
 			}
-			newC <- parseAck(ack)
+			newC <- parseAck(lease.ACK)
 			supervisor.Signal(ctx, supervisor.SignalDone)
 			return nil
 		})
diff --git a/core/pkg/dhcp4c/BUILD.bazel b/core/pkg/dhcp4c/BUILD.bazel
new file mode 100644
index 0000000..6d79268
--- /dev/null
+++ b/core/pkg/dhcp4c/BUILD.bazel
@@ -0,0 +1,32 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "dhcpc.go",
+        "doc.go",
+        "lease.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c",
+    visibility = ["//visibility:public"],
+    deps = [
+        "//core/internal/common/supervisor:go_default_library",
+        "//core/pkg/dhcp4c/transport:go_default_library",
+        "@com_github_cenkalti_backoff_v4//:go_default_library",
+        "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
+        "@com_github_insomniacslk_dhcp//iana:go_default_library",
+    ],
+)
+
+go_test(
+    name = "go_default_test",
+    srcs = ["dhcpc_test.go"],
+    embed = [":go_default_library"],
+    pure = "on",
+    deps = [
+        "//core/pkg/dhcp4c/transport:go_default_library",
+        "@com_github_cenkalti_backoff_v4//:go_default_library",
+        "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
+        "@com_github_stretchr_testify//assert:go_default_library",
+    ],
+)
diff --git a/core/pkg/dhcp4c/dhcpc.go b/core/pkg/dhcp4c/dhcpc.go
new file mode 100644
index 0000000..0811890
--- /dev/null
+++ b/core/pkg/dhcp4c/dhcpc.go
@@ -0,0 +1,677 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package dhcp4c implements a DHCPv4 Client as specified in RFC2131 (with some notable deviations).
+// It implements only the DHCP state machine itself, any configuration other than the interface IP
+// address (which is always assigned in DHCP and necessary for the protocol to work) is exposed
+// as [informers/observables/watchable variables/???] to consumers who then deal with it.
+package dhcp4c
+
+import (
+	"context"
+	"crypto/rand"
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"net"
+	"time"
+
+	"github.com/cenkalti/backoff/v4"
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/insomniacslk/dhcp/iana"
+
+	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/transport"
+)
+
+type state int
+
+const (
+	// stateDiscovering sends broadcast DHCPDISCOVER messages to the network and waits for either a DHCPOFFER or
+	// (in case of Rapid Commit) DHCPACK.
+	stateDiscovering state = iota
+	// stateRequesting sends broadcast DHCPREQUEST messages containing the server identifier for the selected lease and
+	// waits for a DHCPACK or a DHCPNAK. If it doesn't get either it transitions back into discovering.
+	stateRequesting
+	// stateBound just waits until RenewDeadline (derived from RenewTimeValue, half the lifetime by default) expires.
+	stateBound
+	// stateRenewing sends unicast DHCPREQUEST messages to the currently-selected server and waits for either a DHCPACK
+	// or DHCPNAK message. On DHCPACK it transitions to bound, otherwise to discovering.
+	stateRenewing
+	// stateRebinding sends broadcast DHCPREQUEST messages to the network and waits for either a DHCPACK or DHCPNAK from
+	// any server. Response processing is identical to stateRenewing.
+	stateRebinding
+)
+
+func (s state) String() string {
+	switch s {
+	case stateDiscovering:
+		return "DISCOVERING"
+	case stateRequesting:
+		return "REQUESTING"
+	case stateBound:
+		return "BOUND"
+	case stateRenewing:
+		return "RENEWING"
+	case stateRebinding:
+		return "REBINDING"
+	default:
+		return "INVALID"
+	}
+}
+
+// This only requests SubnetMask and IPAddressLeaseTime as renewal and rebinding times are fine if
+// they are just defaulted. They are respected (if valid, otherwise they are clamped to the nearest
+// valid value) if sent by the server.
+var internalOptions = dhcpv4.OptionCodeList{dhcpv4.OptionSubnetMask, dhcpv4.OptionIPAddressLeaseTime}
+
+// Transport represents a mechanism over which DHCP messages can be exchanged with a server.
+type Transport interface {
+	// Send attempts to send the given DHCP payload message to the transport target once. An empty return value
+	// does not indicate that the message was successfully received.
+	Send(payload *dhcpv4.DHCPv4) error
+	// SetReceiveDeadline sets a deadline for Receive() calls after which they return with DeadlineExceededErr
+	SetReceiveDeadline(time.Time) error
+	// Receive waits for a DHCP message to arrive and returns it. If the deadline expires without a message arriving
+	// it will return DeadlineExceededErr. If the message is completely malformed it will an instance of
+	// InvalidMessageError.
+	Receive() (*dhcpv4.DHCPv4, error)
+	// Close closes the given transport. Calls to any of the above methods will fail if the transport is closed.
+	// Specific transports can be reopened after being closed.
+	Close() error
+}
+
+// UnicastTransport represents a mechanism over which DHCP messages can be exchanged with a single server over an
+// arbitrary IPv4-based network. Implementers need to support servers running outside the local network via a router.
+type UnicastTransport interface {
+	Transport
+	// Open connects the transport to a new unicast target. Can only be called after calling Close() or after creating
+	// a new transport.
+	Open(serverIP, bindIP net.IP) error
+}
+
+// BroadcastTransport represents a mechanism over which DHCP messages can be exchanged with all servers on a Layer 2
+// broadcast domain. Implementers need to support sending and receiving messages without any IP being configured on
+// the interface.
+type BroadcastTransport interface {
+	Transport
+	// Open connects the transport. Can only be called after calling Close() or after creating a new transport.
+	Open() error
+}
+
+type LeaseCallback func(old, new *Lease) error
+
+// Client implements a DHCPv4 client.
+//
+// Note that the size of all data sent to the server (RequestedOptions, ClientIdentifier,
+// VendorClassIdentifier and ExtraRequestOptions) should be kept reasonably small (<500 bytes) in
+// order to maximize the chance that requests can be properly transmitted.
+type Client struct {
+	// RequestedOptions contains a list of extra options this client is interested in
+	RequestedOptions dhcpv4.OptionCodeList
+
+	// ClientIdentifier is used by the DHCP server to identify this client.
+	// If empty, on Ethernet the MAC address is used instead.
+	ClientIdentifier []byte
+
+	// VendorClassIdentifier is used by the DHCP server to identify options specific to this type of
+	// clients and to populate the vendor-specific option (43).
+	VendorClassIdentifier string
+
+	// ExtraRequestOptions are extra options sent to the server.
+	ExtraRequestOptions dhcpv4.Options
+
+	// Backoff strategies for each state. These all have sane defaults, override them only if
+	// necessary.
+	DiscoverBackoff    backoff.BackOff
+	AcceptOfferBackoff backoff.BackOff
+	RenewBackoff       backoff.BackOff
+	RebindBackoff      backoff.BackOff
+
+	state state
+
+	lastBoundTransition time.Time
+
+	iface *net.Interface
+
+	// now can be used to override time for testing
+	now func() time.Time
+
+	// LeaseCallback is called every time a lease is aquired, renewed or lost
+	LeaseCallback LeaseCallback
+
+	// Valid in states Discovering, Requesting, Rebinding
+	broadcastConn BroadcastTransport
+
+	// Valid in states Requesting
+	offer *dhcpv4.DHCPv4
+
+	// Valid in states Bound, Renewing
+	unicastConn UnicastTransport
+
+	// Valid in states Bound, Renewing, Rebinding
+	lease              *dhcpv4.DHCPv4
+	leaseDeadline      time.Time
+	leaseBoundDeadline time.Time
+	leaseRenewDeadline time.Time
+}
+
+// newDefaultBackoff returns an infinitely-retrying randomized exponential backoff with a
+// DHCP-appropriate InitialInterval
+func newDefaultBackoff() *backoff.ExponentialBackOff {
+	b := backoff.NewExponentialBackOff()
+	b.MaxElapsedTime = 0 // No Timeout
+	// Lots of servers wait 1s for existing users of an IP. Wait at least for that and keep some
+	// slack for randomization, communication and processing overhead.
+	b.InitialInterval = 1400 * time.Millisecond
+	b.MaxInterval = 30 * time.Second
+	b.RandomizationFactor = 0.2
+	return b
+}
+
+// NewClient instantiates (but doesn't start) a new DHCPv4 client.
+// To have a working client it's required to set LeaseCallback to something that is capable of configuring the IP
+// address on the given interface. Unless managed through external means like a routing protocol, setting the default
+// route is also required. A simple example with the callback package thus looks like this:
+//  c := dhcp4c.NewClient(yourInterface)
+//  c.LeaseCallback = callback.Compose(callback.ManageIP(yourInterface), callback.ManageDefaultRoute(yourInterface))
+//  c.Run(ctx)
+func NewClient(iface *net.Interface) (*Client, error) {
+	broadcastConn := transport.NewBroadcastTransport(iface)
+
+	// broadcastConn needs to be open in stateDiscovering
+	if err := broadcastConn.Open(); err != nil {
+		return nil, fmt.Errorf("failed to create DHCP broadcast transport: %w", err)
+	}
+
+	discoverBackoff := newDefaultBackoff()
+
+	acceptOfferBackoff := newDefaultBackoff()
+	// Abort after 30s and go back to discovering
+	acceptOfferBackoff.MaxElapsedTime = 30 * time.Second
+
+	renewBackoff := newDefaultBackoff()
+	// Increase maximum interval to reduce chatter when the server is down
+	renewBackoff.MaxInterval = 5 * time.Minute
+
+	rebindBackoff := newDefaultBackoff()
+	// Increase maximum interval to reduce chatter when the server is down
+	renewBackoff.MaxInterval = 5 * time.Minute
+
+	return &Client{
+		state:               stateDiscovering,
+		broadcastConn:       broadcastConn,
+		unicastConn:         transport.NewUnicastTransport(iface),
+		iface:               iface,
+		RequestedOptions:    dhcpv4.OptionCodeList{},
+		lastBoundTransition: time.Now(),
+		now:                 time.Now,
+		DiscoverBackoff:     discoverBackoff,
+		AcceptOfferBackoff:  acceptOfferBackoff,
+		RenewBackoff:        renewBackoff,
+		RebindBackoff:       rebindBackoff,
+	}, nil
+}
+
+// acceptableLease checks if the given lease is valid enough to even be processed. This is
+// intentionally not exposed to users because under certain cirumstances it can end up acquiring all
+// available IP addresses from a server.
+func (c *Client) acceptableLease(offer *dhcpv4.DHCPv4) bool {
+	// RFC2131 Section 4.3.1 Table 3
+	if offer.ServerIdentifier() == nil || offer.ServerIdentifier().To4() == nil {
+		return false
+	}
+	// RFC2131 Section 4.3.1 Table 3
+	// Minimum representable lease time is 1s (Section 1.1)
+	if offer.IPAddressLeaseTime(0) < 1*time.Second {
+		return false
+	}
+
+	// Ignore IPs that are in no way valid for an interface (multicast, loopback, ...)
+	if offer.YourIPAddr.To4() == nil || (!offer.YourIPAddr.IsGlobalUnicast() && !offer.YourIPAddr.IsLinkLocalUnicast()) {
+		return false
+	}
+
+	// Technically the options Requested IP address, Parameter request list, Client identifier
+	// and Maximum message size should be refused (MUST NOT), but in the interest of interopatibilty
+	// let's simply remove them if they are present.
+	delete(offer.Options, dhcpv4.OptionRequestedIPAddress.Code())
+	delete(offer.Options, dhcpv4.OptionParameterRequestList.Code())
+	delete(offer.Options, dhcpv4.OptionClientIdentifier.Code())
+	delete(offer.Options, dhcpv4.OptionMaximumDHCPMessageSize.Code())
+
+	// Clamp rebindinding times longer than the lease time. Otherwise the state machine might misbehave.
+	if offer.IPAddressRebindingTime(0) > offer.IPAddressLeaseTime(0) {
+		offer.UpdateOption(dhcpv4.OptGeneric(dhcpv4.OptionRebindingTimeValue, dhcpv4.Duration(offer.IPAddressLeaseTime(0)).ToBytes()))
+	}
+	// Clamp renewal times longer than the rebinding time. Otherwise the state machine might misbehave.
+	if offer.IPAddressRenewalTime(0) > offer.IPAddressRebindingTime(0) {
+		offer.UpdateOption(dhcpv4.OptGeneric(dhcpv4.OptionRenewTimeValue, dhcpv4.Duration(offer.IPAddressRebindingTime(0)).ToBytes()))
+	}
+
+	// Normalize two options that can be represented either inline or as options.
+	if len(offer.ServerHostName) > 0 {
+		offer.Options[uint8(dhcpv4.OptionTFTPServerName)] = []byte(offer.ServerHostName)
+	}
+	if len(offer.BootFileName) > 0 {
+		offer.Options[uint8(dhcpv4.OptionBootfileName)] = []byte(offer.BootFileName)
+	}
+
+	// Normalize siaddr to option 150 (see RFC5859)
+	if len(offer.GetOneOption(dhcpv4.OptionTFTPServerAddress)) == 0 {
+		if offer.ServerIPAddr.To4() != nil && (offer.ServerIPAddr.IsGlobalUnicast() || offer.ServerIPAddr.IsLinkLocalUnicast()) {
+			offer.Options[uint8(dhcpv4.OptionTFTPServerAddress)] = offer.ServerIPAddr.To4()
+		}
+	}
+
+	return true
+}
+
+func earliestDeadline(dl1, dl2 time.Time) time.Time {
+	if dl1.Before(dl2) {
+		return dl1
+	} else {
+		return dl2
+	}
+}
+
+// newXID generates a new transaction ID
+func (c *Client) newXID() (dhcpv4.TransactionID, error) {
+	var xid dhcpv4.TransactionID
+	if _, err := io.ReadFull(rand.Reader, xid[:]); err != nil {
+		return xid, fmt.Errorf("cannot read randomness for transaction ID: %w", err)
+	}
+	return xid, nil
+}
+
+// As most servers out there cannot do reassembly, let's just hope for the best and
+// provide the local interface MTU. If the packet is too big it won't work anyways.
+// Also clamp to the biggest representable MTU in DHCPv4 (2 bytes unsigned int).
+func (c *Client) maxMsgSize() uint16 {
+	if c.iface.MTU < math.MaxUint16 {
+		return uint16(c.iface.MTU)
+	} else {
+		return math.MaxUint16
+	}
+}
+
+// newMsg creates a new DHCP message of a given type and adds common options.
+func (c *Client) newMsg(t dhcpv4.MessageType) (*dhcpv4.DHCPv4, error) {
+	xid, err := c.newXID()
+	if err != nil {
+		return nil, err
+	}
+	opts := make(dhcpv4.Options)
+	opts.Update(dhcpv4.OptMessageType(t))
+	if len(c.ClientIdentifier) > 0 {
+		opts.Update(dhcpv4.OptClientIdentifier(c.ClientIdentifier))
+	}
+	if t == dhcpv4.MessageTypeDiscover || t == dhcpv4.MessageTypeRequest || t == dhcpv4.MessageTypeInform {
+		opts.Update(dhcpv4.OptParameterRequestList(append(c.RequestedOptions, internalOptions...)...))
+		opts.Update(dhcpv4.OptMaxMessageSize(c.maxMsgSize()))
+		if c.VendorClassIdentifier != "" {
+			opts.Update(dhcpv4.OptClassIdentifier(c.VendorClassIdentifier))
+		}
+		for opt, val := range c.ExtraRequestOptions {
+			opts[opt] = val
+		}
+	}
+	return &dhcpv4.DHCPv4{
+		OpCode:        dhcpv4.OpcodeBootRequest,
+		HWType:        iana.HWTypeEthernet,
+		ClientHWAddr:  c.iface.HardwareAddr,
+		HopCount:      0,
+		TransactionID: xid,
+		NumSeconds:    0,
+		Flags:         0,
+		ClientIPAddr:  net.IPv4zero,
+		YourIPAddr:    net.IPv4zero,
+		ServerIPAddr:  net.IPv4zero,
+		GatewayIPAddr: net.IPv4zero,
+		Options:       opts,
+	}, nil
+}
+
+// transactionStateSpec describes a state which is driven by a DHCP message transaction (sending a
+// specific message and then transitioning into a different state depending on the received messages)
+type transactionStateSpec struct {
+	// ctx is a context for canceling the process
+	ctx context.Context
+
+	// transport is used to send and receive messages in this state
+	transport Transport
+
+	// stateDeadline is a fixed external deadline for how long the FSM can remain in this state.
+	// If it's exceeded the stateDeadlineExceeded callback is called and responsible for
+	// transitioning out of this state. It can be left empty to signal that there's no external
+	// deadline for the state.
+	stateDeadline time.Time
+
+	// backoff controls how long to wait for answers until handing control back to the FSM.
+	// Since the FSM hasn't advanced until then this means we just get called again and retransmit.
+	backoff backoff.BackOff
+
+	// requestType is the type of DHCP request sent out in this state. This is used to populate
+	// the default options for the message.
+	requestType dhcpv4.MessageType
+
+	// setExtraOptions can modify the request and set extra options before transmitting. Returning
+	// an error here aborts the FSM an can be used to terminate when no valid request can be
+	// constructed.
+	setExtraOptions func(msg *dhcpv4.DHCPv4) error
+
+	// handleMessage gets called for every parseable (not necessarily valid) DHCP message received
+	// by the transport. It should return an error for every message that doesn't advance the
+	// state machine and no error for every one that does. It is responsible for advancing the FSM
+	// if the required information is present.
+	handleMessage func(msg *dhcpv4.DHCPv4, sentTime time.Time) error
+
+	// stateDeadlineExceeded gets called if either the backoff returns backoff.Stop or the
+	// stateDeadline runs out. It is responsible for advancing the FSM into the next state.
+	stateDeadlineExceeded func() error
+}
+
+func (c *Client) runTransactionState(s transactionStateSpec) error {
+	sentTime := c.now()
+	msg, err := c.newMsg(s.requestType)
+	if err != nil {
+		return fmt.Errorf("failed to get new DHCP message: %w", err)
+	}
+	if err := s.setExtraOptions(msg); err != nil {
+		return fmt.Errorf("failed to create DHCP message: %w", err)
+	}
+
+	wait := s.backoff.NextBackOff()
+	if wait == backoff.Stop {
+		return s.stateDeadlineExceeded()
+	}
+
+	receiveDeadline := sentTime.Add(wait)
+	if !s.stateDeadline.IsZero() {
+		receiveDeadline = earliestDeadline(s.stateDeadline, receiveDeadline)
+	}
+
+	// Jump out if deadline expires in less than 10ms. Minimum lease time is 1s and if we have less
+	// than 10ms to wait for an answer before switching state it makes no sense to send out another
+	// request. This nearly eliminates the problem of sending two different requests back-to-back.
+	if receiveDeadline.Add(-10 * time.Millisecond).Before(sentTime) {
+		return s.stateDeadlineExceeded()
+	}
+
+	if err := s.transport.Send(msg); err != nil {
+		return fmt.Errorf("failed to send message: %w", err)
+	}
+
+	if err := s.transport.SetReceiveDeadline(receiveDeadline); err != nil {
+		return fmt.Errorf("failed to set deadline: %w", err)
+	}
+
+	for {
+		offer, err := s.transport.Receive()
+		select {
+		case <-s.ctx.Done():
+			c.cleanup()
+			return s.ctx.Err()
+		default:
+		}
+		if errors.Is(err, transport.DeadlineExceededErr) {
+			return nil
+		}
+		var e transport.InvalidMessageError
+		if errors.As(err, &e) {
+			// Packet couldn't be read. Maybe log at some point in the future.
+			continue
+		}
+		if err != nil {
+			return fmt.Errorf("failed to receive packet: %w", err)
+		}
+		if offer.TransactionID != msg.TransactionID { // Not our transaction
+			continue
+		}
+		err = s.handleMessage(offer, sentTime)
+		if err == nil {
+			return nil
+		} else if !errors.Is(err, InvalidMsgErr) {
+			return err
+		}
+	}
+}
+
+var InvalidMsgErr = errors.New("invalid message")
+
+func (c *Client) runState(ctx context.Context) error {
+	switch c.state {
+	case stateDiscovering:
+		return c.runTransactionState(transactionStateSpec{
+			ctx:         ctx,
+			transport:   c.broadcastConn,
+			backoff:     c.DiscoverBackoff,
+			requestType: dhcpv4.MessageTypeDiscover,
+			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
+				msg.UpdateOption(dhcpv4.OptGeneric(dhcpv4.OptionRapidCommit, []byte{}))
+				return nil
+			},
+			handleMessage: func(offer *dhcpv4.DHCPv4, sentTime time.Time) error {
+				switch offer.MessageType() {
+				case dhcpv4.MessageTypeOffer:
+					if c.acceptableLease(offer) {
+						c.offer = offer
+						c.AcceptOfferBackoff.Reset()
+						c.state = stateRequesting
+						return nil
+					}
+				case dhcpv4.MessageTypeAck:
+					if c.acceptableLease(offer) {
+						return c.transitionToBound(offer, sentTime)
+					}
+				}
+				return InvalidMsgErr
+			},
+		})
+	case stateRequesting:
+		return c.runTransactionState(transactionStateSpec{
+			ctx:         ctx,
+			transport:   c.broadcastConn,
+			backoff:     c.AcceptOfferBackoff,
+			requestType: dhcpv4.MessageTypeRequest,
+			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
+				msg.UpdateOption(dhcpv4.OptServerIdentifier(c.offer.ServerIdentifier()))
+				msg.TransactionID = c.offer.TransactionID
+				msg.UpdateOption(dhcpv4.OptRequestedIPAddress(c.offer.YourIPAddr))
+				return nil
+			},
+			handleMessage: func(msg *dhcpv4.DHCPv4, sentTime time.Time) error {
+				switch msg.MessageType() {
+				case dhcpv4.MessageTypeAck:
+					if c.acceptableLease(msg) {
+						return c.transitionToBound(msg, sentTime)
+					}
+				case dhcpv4.MessageTypeNak:
+					c.requestingToDiscovering()
+					return nil
+				}
+				return InvalidMsgErr
+			},
+			stateDeadlineExceeded: func() error {
+				c.requestingToDiscovering()
+				return nil
+			},
+		})
+	case stateBound:
+		select {
+		case <-time.After(c.leaseBoundDeadline.Sub(c.now())):
+			c.state = stateRenewing
+			c.RenewBackoff.Reset()
+			return nil
+		case <-ctx.Done():
+			c.cleanup()
+			return ctx.Err()
+		}
+	case stateRenewing:
+		return c.runTransactionState(transactionStateSpec{
+			ctx:           ctx,
+			transport:     c.unicastConn,
+			backoff:       c.RenewBackoff,
+			requestType:   dhcpv4.MessageTypeRequest,
+			stateDeadline: c.leaseRenewDeadline,
+			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
+				msg.ClientIPAddr = c.lease.YourIPAddr
+				return nil
+			},
+			handleMessage: func(ack *dhcpv4.DHCPv4, sentTime time.Time) error {
+				switch ack.MessageType() {
+				case dhcpv4.MessageTypeAck:
+					if c.acceptableLease(ack) {
+						return c.transitionToBound(ack, sentTime)
+					}
+				case dhcpv4.MessageTypeNak:
+					return c.leaseToDiscovering()
+				}
+				return InvalidMsgErr
+			},
+			stateDeadlineExceeded: func() error {
+				c.state = stateRebinding
+				if err := c.switchToBroadcast(); err != nil {
+					return fmt.Errorf("failed to switch to broadcast: %w", err)
+				}
+				c.RebindBackoff.Reset()
+				return nil
+			},
+		})
+	case stateRebinding:
+		return c.runTransactionState(transactionStateSpec{
+			ctx:           ctx,
+			transport:     c.broadcastConn,
+			backoff:       c.RebindBackoff,
+			stateDeadline: c.leaseDeadline,
+			requestType:   dhcpv4.MessageTypeRequest,
+			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
+				msg.ClientIPAddr = c.lease.YourIPAddr
+				return nil
+			},
+			handleMessage: func(ack *dhcpv4.DHCPv4, sentTime time.Time) error {
+				switch ack.MessageType() {
+				case dhcpv4.MessageTypeAck:
+					if c.acceptableLease(ack) {
+						return c.transitionToBound(ack, sentTime)
+					}
+				case dhcpv4.MessageTypeNak:
+					return c.leaseToDiscovering()
+				}
+				return InvalidMsgErr
+			},
+			stateDeadlineExceeded: func() error {
+				return c.leaseToDiscovering()
+			},
+		})
+	}
+	return errors.New("state machine in invalid state")
+}
+
+func (c *Client) Run(ctx context.Context) error {
+	if c.LeaseCallback == nil {
+		panic("LeaseCallback must be set before calling Run")
+	}
+	logger := supervisor.Logger(ctx)
+	for {
+		oldState := c.state
+		if err := c.runState(ctx); err != nil {
+			return err
+		}
+		if c.state != oldState {
+			logger.Infof("%s => %s", oldState, c.state)
+		}
+	}
+}
+
+func (c *Client) cleanup() {
+	c.unicastConn.Close()
+	if c.lease != nil {
+		c.LeaseCallback(leaseFromAck(c.lease, c.leaseDeadline), nil)
+	}
+	c.broadcastConn.Close()
+}
+
+func (c *Client) requestingToDiscovering() {
+	c.offer = nil
+	c.DiscoverBackoff.Reset()
+	c.state = stateDiscovering
+}
+
+func (c *Client) leaseToDiscovering() error {
+	if c.state == stateRenewing {
+		if err := c.switchToBroadcast(); err != nil {
+			return err
+		}
+	}
+	c.state = stateDiscovering
+	c.DiscoverBackoff.Reset()
+	if err := c.LeaseCallback(leaseFromAck(c.lease, c.leaseDeadline), nil); err != nil {
+		return fmt.Errorf("lease callback failed: %w", err)
+	}
+	c.lease = nil
+	return nil
+}
+
+func leaseFromAck(ack *dhcpv4.DHCPv4, expiresAt time.Time) *Lease {
+	if ack == nil {
+		return nil
+	}
+	return &Lease{Options: ack.Options, AssignedIP: ack.YourIPAddr, ExpiresAt: expiresAt}
+}
+
+func (c *Client) transitionToBound(ack *dhcpv4.DHCPv4, sentTime time.Time) error {
+	// Guaranteed to exist, leases without a lease time are filtered
+	leaseTime := ack.IPAddressLeaseTime(0)
+	origLeaseDeadline := c.leaseDeadline
+	c.leaseDeadline = sentTime.Add(leaseTime)
+	c.leaseBoundDeadline = sentTime.Add(ack.IPAddressRenewalTime(time.Duration(float64(leaseTime) * 0.5)))
+	c.leaseRenewDeadline = sentTime.Add(ack.IPAddressRebindingTime(time.Duration(float64(leaseTime) * 0.85)))
+
+	if err := c.LeaseCallback(leaseFromAck(c.lease, origLeaseDeadline), leaseFromAck(ack, c.leaseDeadline)); err != nil {
+		return fmt.Errorf("lease callback failed: %w", err)
+	}
+
+	if c.state != stateRenewing {
+		if err := c.switchToUnicast(ack.ServerIdentifier(), ack.YourIPAddr); err != nil {
+			return fmt.Errorf("failed to switch transports: %w", err)
+		}
+	}
+	c.state = stateBound
+	c.lease = ack
+	return nil
+}
+
+func (c *Client) switchToUnicast(serverIP, bindIP net.IP) error {
+	if err := c.broadcastConn.Close(); err != nil {
+		return fmt.Errorf("failed to close broadcast transport: %w", err)
+	}
+	if err := c.unicastConn.Open(serverIP, bindIP); err != nil {
+		return fmt.Errorf("failed to open unicast transport: %w", err)
+	}
+	return nil
+}
+
+func (c *Client) switchToBroadcast() error {
+	if err := c.unicastConn.Close(); err != nil {
+		return fmt.Errorf("failed to close unicast transport: %w", err)
+	}
+	if err := c.broadcastConn.Open(); err != nil {
+		return fmt.Errorf("failed to open broadcast transport: %w", err)
+	}
+	return nil
+}
diff --git a/core/pkg/dhcp4c/dhcpc_test.go b/core/pkg/dhcp4c/dhcpc_test.go
new file mode 100644
index 0000000..4c5fb11
--- /dev/null
+++ b/core/pkg/dhcp4c/dhcpc_test.go
@@ -0,0 +1,514 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package dhcp4c
+
+import (
+	"context"
+	"fmt"
+	"net"
+	"testing"
+	"time"
+
+	"github.com/cenkalti/backoff/v4"
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/stretchr/testify/assert"
+
+	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/transport"
+)
+
+type fakeTime struct {
+	time time.Time
+}
+
+func newFakeTime(t time.Time) *fakeTime {
+	return &fakeTime{
+		time: t,
+	}
+}
+
+func (ft *fakeTime) Now() time.Time {
+	return ft.time
+}
+
+func (ft *fakeTime) Advance(d time.Duration) {
+	ft.time = ft.time.Add(d)
+}
+
+type mockTransport struct {
+	sentPacket     *dhcpv4.DHCPv4
+	sendError      error
+	setDeadline    time.Time
+	receivePackets []*dhcpv4.DHCPv4
+	receiveError   error
+	receiveIdx     int
+	closed         bool
+}
+
+func (mt *mockTransport) sendPackets(pkts ...*dhcpv4.DHCPv4) {
+	mt.receiveIdx = 0
+	mt.receivePackets = pkts
+}
+
+func (mt *mockTransport) Open() error {
+	mt.closed = false
+	return nil
+}
+
+func (mt *mockTransport) Send(payload *dhcpv4.DHCPv4) error {
+	mt.sentPacket = payload
+	return mt.sendError
+}
+
+func (mt *mockTransport) Receive() (*dhcpv4.DHCPv4, error) {
+	if mt.receiveError != nil {
+		return nil, mt.receiveError
+	}
+	if len(mt.receivePackets) > mt.receiveIdx {
+		packet := mt.receivePackets[mt.receiveIdx]
+		packet, err := dhcpv4.FromBytes(packet.ToBytes()) // Clone packet
+		if err != nil {
+			panic("ToBytes => FromBytes failed")
+		}
+		packet.TransactionID = mt.sentPacket.TransactionID
+		mt.receiveIdx++
+		return packet, nil
+	}
+	return nil, transport.DeadlineExceededErr
+}
+
+func (mt *mockTransport) SetReceiveDeadline(t time.Time) error {
+	mt.setDeadline = t
+	return nil
+}
+
+func (mt *mockTransport) Close() error {
+	mt.closed = true
+	return nil
+}
+
+type unicastMockTransport struct {
+	mockTransport
+	serverIP net.IP
+	bindIP   net.IP
+}
+
+func (umt *unicastMockTransport) Open(serverIP, bindIP net.IP) error {
+	if umt.serverIP != nil {
+		panic("double-open of unicast transport")
+	}
+	umt.serverIP = serverIP
+	umt.bindIP = bindIP
+	return nil
+}
+
+func (umt *unicastMockTransport) Close() error {
+	umt.serverIP = nil
+	umt.bindIP = nil
+	return umt.mockTransport.Close()
+}
+
+type mockBackoff struct {
+	indefinite bool
+	values     []time.Duration
+	idx        int
+}
+
+func newMockBackoff(vals []time.Duration, indefinite bool) *mockBackoff {
+	return &mockBackoff{values: vals, indefinite: indefinite}
+}
+
+func (mb *mockBackoff) NextBackOff() time.Duration {
+	if mb.idx < len(mb.values) || mb.indefinite {
+		val := mb.values[mb.idx%len(mb.values)]
+		mb.idx++
+		return val
+	}
+	return backoff.Stop
+}
+
+func (mb *mockBackoff) Reset() {
+	mb.idx = 0
+}
+
+func TestClient_runTransactionState(t *testing.T) {
+	ft := newFakeTime(time.Date(2020, 10, 28, 15, 02, 32, 352, time.UTC))
+	c := Client{
+		now:   ft.Now,
+		iface: &net.Interface{MTU: 9324, HardwareAddr: net.HardwareAddr{0x12, 0x23, 0x34, 0x45, 0x56, 0x67}},
+	}
+	mt := &mockTransport{}
+	err := c.runTransactionState(transactionStateSpec{
+		ctx:         context.Background(),
+		transport:   mt,
+		backoff:     newMockBackoff([]time.Duration{1 * time.Second}, true),
+		requestType: dhcpv4.MessageTypeDiscover,
+		setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
+			msg.UpdateOption(dhcpv4.OptDomainName("just.testing.invalid"))
+			return nil
+		},
+		handleMessage: func(msg *dhcpv4.DHCPv4, sentTime time.Time) error {
+			return nil
+		},
+		stateDeadlineExceeded: func() error {
+			panic("shouldn't be called")
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, "just.testing.invalid", mt.sentPacket.DomainName())
+	assert.Equal(t, dhcpv4.MessageTypeDiscover, mt.sentPacket.MessageType())
+}
+
+// TestAcceptableLease tests if a minimal valid lease is accepted by acceptableLease
+func TestAcceptableLease(t *testing.T) {
+	c := Client{}
+	offer := &dhcpv4.DHCPv4{
+		OpCode: dhcpv4.OpcodeBootReply,
+	}
+	offer.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeOffer))
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
+	offer.YourIPAddr = net.IP{192, 0, 2, 2}
+	assert.True(t, c.acceptableLease(offer), "Valid lease is not acceptable")
+}
+
+type dhcpClientPuppet struct {
+	ft  *fakeTime
+	bmt *mockTransport
+	umt *unicastMockTransport
+	c   *Client
+}
+
+func newPuppetClient(initState state) *dhcpClientPuppet {
+	ft := newFakeTime(time.Date(2020, 10, 28, 15, 02, 32, 352, time.UTC))
+	bmt := &mockTransport{}
+	umt := &unicastMockTransport{}
+	c := &Client{
+		state:              initState,
+		now:                ft.Now,
+		iface:              &net.Interface{MTU: 9324, HardwareAddr: net.HardwareAddr{0x12, 0x23, 0x34, 0x45, 0x56, 0x67}},
+		broadcastConn:      bmt,
+		unicastConn:        umt,
+		DiscoverBackoff:    newMockBackoff([]time.Duration{1 * time.Second}, true),
+		AcceptOfferBackoff: newMockBackoff([]time.Duration{1 * time.Second, 2 * time.Second}, false),
+		RenewBackoff:       newMockBackoff([]time.Duration{1 * time.Second}, true),
+		RebindBackoff:      newMockBackoff([]time.Duration{1 * time.Second}, true),
+	}
+	return &dhcpClientPuppet{
+		ft:  ft,
+		bmt: bmt,
+		umt: umt,
+		c:   c,
+	}
+}
+
+func newResponse(m dhcpv4.MessageType) *dhcpv4.DHCPv4 {
+	o := &dhcpv4.DHCPv4{
+		OpCode: dhcpv4.OpcodeBootReply,
+	}
+	o.UpdateOption(dhcpv4.OptMessageType(m))
+	return o
+}
+
+// TestDiscoverOffer tests if the DHCP state machine in discovering state properly selects the first valid lease
+// and transitions to requesting state
+func TestDiscoverRequesting(t *testing.T) {
+	p := newPuppetClient(stateDiscovering)
+
+	// A minimal valid lease
+	offer := newResponse(dhcpv4.MessageTypeOffer)
+	testIP := net.IP{192, 0, 2, 2}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
+	offer.YourIPAddr = testIP
+
+	// Intentionally bad offer with no lease time.
+	terribleOffer := newResponse(dhcpv4.MessageTypeOffer)
+	terribleOffer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 2}))
+	terribleOffer.YourIPAddr = net.IPv4(192, 0, 2, 2)
+
+	// Send the bad offer first, then the valid offer
+	p.bmt.sendPackets(terribleOffer, offer)
+
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	assert.Equal(t, stateRequesting, p.c.state, "DHCP client didn't process offer")
+	assert.Equal(t, testIP, p.c.offer.YourIPAddr, "DHCP client requested invalid offer")
+}
+
+// TestOfferBound tests if the DHCP state machine in requesting state processes a valid DHCPACK and transitions to
+// bound state.
+func TestRequestingBound(t *testing.T) {
+	p := newPuppetClient(stateRequesting)
+
+	offer := newResponse(dhcpv4.MessageTypeAck)
+	testIP := net.IP{192, 0, 2, 2}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
+	offer.YourIPAddr = testIP
+
+	p.bmt.sendPackets(offer)
+	p.c.offer = offer
+	p.c.LeaseCallback = func(old, new *Lease) error {
+		assert.Nil(t, old, "old lease is not nil for new lease")
+		assert.Equal(t, testIP, new.AssignedIP, "new lease has wrong IP")
+		return nil
+	}
+
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't process offer")
+	assert.Equal(t, testIP, p.c.lease.YourIPAddr, "DHCP client requested invalid offer")
+}
+
+// TestRequestingDiscover tests if the DHCP state machine in requesting state transitions back to discovering if it
+// takes too long to get a valid DHCPACK.
+func TestRequestingDiscover(t *testing.T) {
+	p := newPuppetClient(stateRequesting)
+
+	offer := newResponse(dhcpv4.MessageTypeOffer)
+	testIP := net.IP{192, 0, 2, 2}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
+	offer.YourIPAddr = testIP
+	p.c.offer = offer
+
+	for i := 0; i < 10; i++ {
+		p.bmt.sendPackets()
+		if err := p.c.runState(context.Background()); err != nil {
+			t.Error(err)
+		}
+		assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType(), "Invalid message type for requesting")
+		if p.c.state == stateDiscovering {
+			break
+		}
+		p.ft.time = p.bmt.setDeadline
+
+		if i == 9 {
+			t.Fatal("Too many tries while requesting, backoff likely wrong")
+		}
+	}
+	assert.Equal(t, stateDiscovering, p.c.state, "DHCP client didn't switch back to offer after requesting expired")
+}
+
+// TestDiscoverRapidCommit tests if the DHCP state machine in discovering state transitions directly to bound if a
+// rapid commit response (DHCPACK) is received.
+func TestDiscoverRapidCommit(t *testing.T) {
+	testIP := net.IP{192, 0, 2, 2}
+	offer := newResponse(dhcpv4.MessageTypeAck)
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
+	leaseTime := 10 * time.Second
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
+	offer.YourIPAddr = testIP
+
+	p := newPuppetClient(stateDiscovering)
+	p.c.LeaseCallback = func(old, new *Lease) error {
+		assert.Nil(t, old, "old is not nil")
+		assert.Equal(t, testIP, new.AssignedIP, "callback called with wrong IP")
+		assert.Equal(t, p.ft.Now().Add(leaseTime), new.ExpiresAt, "invalid ExpiresAt")
+		return nil
+	}
+	p.bmt.sendPackets(offer)
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't process offer")
+	assert.Equal(t, testIP, p.c.lease.YourIPAddr, "DHCP client requested invalid offer")
+	assert.Equal(t, 5*time.Second, p.c.leaseBoundDeadline.Sub(p.ft.Now()), "Renewal time was incorrectly defaulted")
+}
+
+type TestOption uint8
+
+func (o TestOption) Code() uint8 {
+	return uint8(o) + 224 // Private options
+}
+func (o TestOption) String() string {
+	return fmt.Sprintf("Test Option %d", uint8(o))
+}
+
+// TestBoundRenewingBound tests if the DHCP state machine in bound correctly transitions to renewing after
+// leaseBoundDeadline expires, sends a DHCPREQUEST and after it gets a DHCPACK response calls LeaseCallback and
+// transitions back to bound with correct new deadlines.
+func TestBoundRenewingBound(t *testing.T) {
+	offer := newResponse(dhcpv4.MessageTypeAck)
+	testIP := net.IP{192, 0, 2, 2}
+	serverIP := net.IP{192, 0, 2, 1}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
+	leaseTime := 10 * time.Second
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
+	offer.YourIPAddr = testIP
+
+	p := newPuppetClient(stateBound)
+	p.umt.Open(serverIP, testIP)
+	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
+	// Other deadlines are intentionally empty to make sure they aren't used
+	p.c.leaseRenewDeadline = p.ft.Now().Add(8500 * time.Millisecond)
+	p.c.leaseBoundDeadline = p.ft.Now().Add(5000 * time.Millisecond)
+
+	p.ft.Advance(5*time.Second - 5*time.Millisecond)
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	p.ft.Advance(5 * time.Millisecond) // We cannot intercept time.After so we just advance the clock by the time slept
+	assert.Equal(t, stateRenewing, p.c.state, "DHCP client not renewing")
+	offer.UpdateOption(dhcpv4.OptGeneric(TestOption(1), []byte{0x12}))
+	p.umt.sendPackets(offer)
+	p.c.LeaseCallback = func(old, new *Lease) error {
+		assert.Equal(t, testIP, old.AssignedIP, "callback called with wrong old IP")
+		assert.Equal(t, testIP, new.AssignedIP, "callback called with wrong IP")
+		assert.Equal(t, p.ft.Now().Add(leaseTime), new.ExpiresAt, "invalid ExpiresAt")
+		assert.Empty(t, old.Options.Get(TestOption(1)), "old contains options from new")
+		assert.Equal(t, []byte{0x12}, new.Options.Get(TestOption(1)), "renewal didn't add new option")
+		return nil
+	}
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't renew")
+	assert.Equal(t, p.ft.Now().Add(leaseTime), p.c.leaseDeadline, "lease deadline not updated")
+	assert.Equal(t, dhcpv4.MessageTypeRequest, p.umt.sentPacket.MessageType(), "Invalid message type for renewal")
+}
+
+// TestRenewingRebinding tests if the DHCP state machine in renewing state correctly sends DHCPREQUESTs and transitions
+// to the rebinding state when it hasn't received a valid response until the deadline expires.
+func TestRenewingRebinding(t *testing.T) {
+	offer := newResponse(dhcpv4.MessageTypeAck)
+	testIP := net.IP{192, 0, 2, 2}
+	serverIP := net.IP{192, 0, 2, 1}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
+	leaseTime := 10 * time.Second
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
+	offer.YourIPAddr = testIP
+
+	p := newPuppetClient(stateRenewing)
+	p.umt.Open(serverIP, testIP)
+	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
+	// Other deadlines are intentionally empty to make sure they aren't used
+	p.c.leaseRenewDeadline = p.ft.Now().Add(8500 * time.Millisecond)
+	p.c.leaseDeadline = p.ft.Now().Add(10000 * time.Millisecond)
+
+	startTime := p.ft.Now()
+	p.ft.Advance(5 * time.Second)
+
+	p.c.LeaseCallback = func(old, new *Lease) error {
+		t.Fatal("Lease callback called without valid offer")
+		return nil
+	}
+
+	for i := 0; i < 10; i++ {
+		p.umt.sendPackets()
+		if err := p.c.runState(context.Background()); err != nil {
+			t.Error(err)
+		}
+		assert.Equal(t, dhcpv4.MessageTypeRequest, p.umt.sentPacket.MessageType(), "Invalid message type for renewal")
+		p.ft.time = p.umt.setDeadline
+
+		if p.c.state == stateRebinding {
+			break
+		}
+		if i == 9 {
+			t.Fatal("Too many tries while renewing, backoff likely wrong")
+		}
+	}
+	assert.Equal(t, startTime.Add(8500*time.Millisecond), p.umt.setDeadline, "wrong listen deadline when renewing")
+	assert.Equal(t, stateRebinding, p.c.state, "DHCP client not renewing")
+	assert.False(t, p.bmt.closed)
+	assert.True(t, p.umt.closed)
+}
+
+// TestRebindingBound tests if the DHCP state machine in rebinding state sends DHCPREQUESTs to the network and if
+// it receives a valid DHCPACK correctly transitions back to bound state.
+func TestRebindingBound(t *testing.T) {
+	offer := newResponse(dhcpv4.MessageTypeAck)
+	testIP := net.IP{192, 0, 2, 2}
+	serverIP := net.IP{192, 0, 2, 1}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
+	leaseTime := 10 * time.Second
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
+	offer.YourIPAddr = testIP
+
+	p := newPuppetClient(stateRebinding)
+	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
+	// Other deadlines are intentionally empty to make sure they aren't used
+	p.c.leaseDeadline = p.ft.Now().Add(10000 * time.Millisecond)
+
+	p.ft.Advance(9 * time.Second)
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType(), "DHCP rebind sent invalid message type")
+	assert.Equal(t, stateRebinding, p.c.state, "DHCP client transferred out of rebinding state without trigger")
+	offer.UpdateOption(dhcpv4.OptGeneric(TestOption(1), []byte{0x12})) // Mark answer
+	p.bmt.sendPackets(offer)
+	p.bmt.sentPacket = nil
+	p.c.LeaseCallback = func(old, new *Lease) error {
+		assert.Equal(t, testIP, old.AssignedIP, "callback called with wrong old IP")
+		assert.Equal(t, testIP, new.AssignedIP, "callback called with wrong IP")
+		assert.Equal(t, p.ft.Now().Add(leaseTime), new.ExpiresAt, "invalid ExpiresAt")
+		assert.Empty(t, old.Options.Get(TestOption(1)), "old contains options from new")
+		assert.Equal(t, []byte{0x12}, new.Options.Get(TestOption(1)), "renewal didn't add new option")
+		return nil
+	}
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Error(err)
+	}
+	assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType())
+	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't go back to bound")
+}
+
+// TestRebindingBound tests if the DHCP state machine in rebinding state transitions to discovering state if
+// leaseDeadline expires and calls LeaseCallback with an empty new lease.
+func TestRebindingDiscovering(t *testing.T) {
+	offer := newResponse(dhcpv4.MessageTypeAck)
+	testIP := net.IP{192, 0, 2, 2}
+	serverIP := net.IP{192, 0, 2, 1}
+	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
+	leaseTime := 10 * time.Second
+	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
+	offer.YourIPAddr = testIP
+
+	p := newPuppetClient(stateRebinding)
+	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
+	// Other deadlines are intentionally empty to make sure they aren't used
+	p.c.leaseDeadline = p.ft.Now().Add(10000 * time.Millisecond)
+
+	p.ft.Advance(9 * time.Second)
+	p.c.LeaseCallback = func(old, new *Lease) error {
+		assert.Equal(t, testIP, old.AssignedIP, "callback called with wrong old IP")
+		assert.Nil(t, new, "transition to discovering didn't clear new lease on callback")
+		return nil
+	}
+	for i := 0; i < 10; i++ {
+		p.bmt.sendPackets()
+		p.bmt.sentPacket = nil
+		if err := p.c.runState(context.Background()); err != nil {
+			t.Error(err)
+		}
+		if p.c.state == stateDiscovering {
+			assert.Nil(t, p.bmt.sentPacket)
+			break
+		}
+		assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType(), "Invalid message type for rebind")
+		p.ft.time = p.bmt.setDeadline
+		if i == 9 {
+			t.Fatal("Too many tries while rebinding, backoff likely wrong")
+		}
+	}
+	assert.Nil(t, p.c.lease, "Lease not zeroed on transition to discovering")
+	assert.Equal(t, stateDiscovering, p.c.state, "DHCP client didn't transition to discovering after loosing lease")
+}
diff --git a/core/pkg/dhcp4c/doc.go b/core/pkg/dhcp4c/doc.go
new file mode 100644
index 0000000..b270c7b
--- /dev/null
+++ b/core/pkg/dhcp4c/doc.go
@@ -0,0 +1,53 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package dhcp4c provides a client implementation of the DHCPv4 protocol (RFC2131) and a few extensions for Linux-based
+// systems.
+// The code is split into three main parts:
+// - The core DHCP state machine, which lives in dhcpc.go
+// - Mechanisms to send and receive DHCP messages, which live in transport/
+// - Standard callbacks which implement necessary kernel configuration steps in a simple and standalone way living in
+//   callback/
+//
+// Since the DHCP protocol is ugly and underspecified (see https://tools.ietf.org/html/draft-ietf-dhc-implementation-02
+// for a subset of known issues), this client slightly bends the specification in the following cases:
+// - IP fragmentation for DHCP messages is not supported for both sending and receiving messages
+//   This is because the major servers (ISC, dnsmasq, ...) do not implement it and just drop fragmented packets, so it
+//   would be counterproductive to try to send them. The client just attempts to send the full message and hopes it
+//   passes through to the server.
+// - The suggested timeouts and wait periods have been tightened significantly. When the standard was written 10Mbps
+//   Ethernet with hubs was a common interconnect. Using these would make the client extremely slow on today's
+//   1Gbps+ networks.
+// - Wrong data in DHCP responses is fixed up if possible. This fixing includes dropping prohibited options, clamping
+//   semantically invalid data and defaulting not set options as far as it's possible. Non-recoverable responses
+//   (for example because a non-Unicast IP is handed out or lease time is not set or zero) are still ignored.
+//   All data which can be stored in both DHCP fields and options is also normalized to the corresponding option.
+// - Duplicate Address Detection is not implemented by default. It's slow, hard to implement correctly and generally
+//   not necessary on modern networks as the servers already waste time checking for duplicate addresses. It's possible
+//   to hook it in via a LeaseCallback if necessary in a given application.
+//
+// Operationally, there's one known caveat to using this client: If the lease offered during the select phase (in a
+// DHCPOFFER) is not the same as the one sent in the following DHCPACK the first one might be acceptable, but the second
+// one might not be. This can cause pathological behavior where the client constantly switches between discovering and
+// requesting states. Depending on the reuse policies on the DHCP server this can cause the client to consume all
+// available IP addresses. Sadly there's no good way of fixing this within the boundaries of the protocol. A DHCPRELEASE
+// for the adresse would need to be unicasted so the unaccepable address would need to be configured which can be either
+// impossible if it's not valid or not acceptable from a security standpoint (for example because it overlaps with a
+// prefix used internally) and a DHCPDECLINE would cause the server to blacklist the IP thus also depleting the IP pool.
+// This could be potentially avoided by originating DHCPRELEASE packages from a userspace transport, but said transport
+// would need to be routing- and PMTU-aware which would make it even more complicated than the existing
+// BroadcastTransport.
+package dhcp4c
diff --git a/core/pkg/dhcp4c/lease.go b/core/pkg/dhcp4c/lease.go
new file mode 100644
index 0000000..ab6da40
--- /dev/null
+++ b/core/pkg/dhcp4c/lease.go
@@ -0,0 +1,74 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package dhcp4c
+
+import (
+	"net"
+	"time"
+
+	"github.com/insomniacslk/dhcp/dhcpv4"
+)
+
+// Lease represents a DHCPv4 lease. It only consists of an IP, an expiration timestamp and options as all other
+// relevant parts of the message have been normalized into their respective options. It also contains some smart
+// getters for commonly-used options which extract only valid information from options.
+type Lease struct {
+	AssignedIP net.IP
+	ExpiresAt  time.Time
+	Options    dhcpv4.Options
+}
+
+// SubnetMask returns the SubnetMask option or the default mask if not set or invalid.
+// It returns nil if the lease is nil.
+func (l *Lease) SubnetMask() net.IPMask {
+	if l == nil {
+		return nil
+	}
+	mask := net.IPMask(dhcpv4.GetIP(dhcpv4.OptionSubnetMask, l.Options))
+	if _, bits := mask.Size(); bits != 32 { // If given mask is not valid, use the default mask
+		mask = l.AssignedIP.DefaultMask()
+	}
+	return mask
+}
+
+// IPNet returns an IPNet from the assigned IP and subnet mask.
+// It returns nil if the lease is nil.
+func (l *Lease) IPNet() *net.IPNet {
+	if l == nil {
+		return nil
+	}
+	return &net.IPNet{
+		IP:   l.AssignedIP,
+		Mask: l.SubnetMask(),
+	}
+}
+
+// Router returns the first valid router from the DHCP router option or nil if none such exists.
+// It returns nil if the lease is nil.
+func (l *Lease) Router() net.IP {
+	if l == nil {
+		return nil
+	}
+	routers := dhcpv4.GetIPs(dhcpv4.OptionRouter, l.Options)
+	for _, r := range routers {
+		if r.IsGlobalUnicast() || r.IsLinkLocalUnicast() {
+			return r
+		}
+	}
+	// No (valid) router found
+	return nil
+}
diff --git a/core/pkg/dhcp4c/transport/BUILD.bazel b/core/pkg/dhcp4c/transport/BUILD.bazel
new file mode 100644
index 0000000..7ee17f6
--- /dev/null
+++ b/core/pkg/dhcp4c/transport/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "transport.go",
+        "transport_broadcast.go",
+        "transport_unicast.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/transport",
+    visibility = ["//visibility:public"],
+    deps = [
+        "@com_github_google_gopacket//:go_default_library",
+        "@com_github_google_gopacket//layers:go_default_library",
+        "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
+        "@com_github_mdlayher_raw//:go_default_library",
+        "@org_golang_x_net//bpf:go_default_library",
+        "@org_golang_x_sys//unix:go_default_library",
+    ],
+)
diff --git a/core/pkg/dhcp4c/transport/transport.go b/core/pkg/dhcp4c/transport/transport.go
new file mode 100644
index 0000000..8f5f791
--- /dev/null
+++ b/core/pkg/dhcp4c/transport/transport.go
@@ -0,0 +1,50 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package transport contains Linux-based transports for the DHCP broadcast and unicast
+// specifications.
+package transport
+
+import (
+	"errors"
+	"fmt"
+	"net"
+)
+
+var DeadlineExceededErr = errors.New("deadline exceeded")
+
+func NewInvalidMessageError(internalErr error) error {
+	return &InvalidMessageError{internalErr: internalErr}
+}
+
+type InvalidMessageError struct {
+	internalErr error
+}
+
+func (i InvalidMessageError) Error() string {
+	return fmt.Sprintf("received invalid packet: %v", i.internalErr.Error())
+}
+
+func (i InvalidMessageError) Unwrap() error {
+	return i.internalErr
+}
+
+func deadlineFromTimeout(err error) error {
+	if timeoutErr, ok := err.(net.Error); ok && timeoutErr.Timeout() {
+		return DeadlineExceededErr
+	}
+	return err
+}
diff --git a/core/pkg/dhcp4c/transport/transport_broadcast.go b/core/pkg/dhcp4c/transport/transport_broadcast.go
new file mode 100644
index 0000000..79fad7d
--- /dev/null
+++ b/core/pkg/dhcp4c/transport/transport_broadcast.go
@@ -0,0 +1,207 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package transport
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"net"
+	"time"
+
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/mdlayher/raw"
+	"golang.org/x/net/bpf"
+)
+
+const (
+	// RFC2474 Section 4.2.2.1 with reference to RFC791 Section 3.1 (Network Control Precedence)
+	dscpCS7 = 0x7 << 3
+
+	// IPv4 MTU
+	maxIPv4MTU = math.MaxUint16 // IPv4 "Total Length" field is an unsigned 16 bit integer
+)
+
+// mustAssemble calls bpf.Assemble and panics if it retuns an error.
+func mustAssemble(insns []bpf.Instruction) []bpf.RawInstruction {
+	rawInsns, err := bpf.Assemble(insns)
+	if err != nil {
+		panic("mustAssemble failed to assemble BPF: " + err.Error())
+	}
+	return rawInsns
+}
+
+// BPF filter for UDP in IPv4 with destination port 68 (DHCP Client)
+//
+// This is used to make the kernel drop non-DHCP traffic for us so that we don't have to handle
+// excessive unrelated traffic flowing on a given link which might overwhelm the single-threaded
+// receiver.
+var bpfFilterInstructions = []bpf.Instruction{
+	// Check IP protocol version equals 4 (first 4 bits of the first byte)
+	// With Ethernet II framing, this is more of a sanity check. We already request the kernel
+	// to only return EtherType 0x0800 (IPv4) frames.
+	bpf.LoadAbsolute{Off: 0, Size: 1},
+	bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 0xf0}, // SubnetMask second 4 bits
+	bpf.JumpIf{Cond: bpf.JumpEqual, Val: 4 << 4, SkipTrue: 1},
+	bpf.RetConstant{Val: 0}, // Discard
+
+	// Check IPv4 Protocol byte (offset 9) equals UDP
+	bpf.LoadAbsolute{Off: 9, Size: 1},
+	bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(layers.IPProtocolUDP), SkipTrue: 1},
+	bpf.RetConstant{Val: 0}, // Discard
+
+	// Check if IPv4 fragment offset is all-zero (this is not a fragment)
+	bpf.LoadAbsolute{Off: 6, Size: 2},
+	bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 0x1fff, SkipFalse: 1},
+	bpf.RetConstant{Val: 0}, // Discard
+
+	// Load IPv4 header size from offset zero and store it into X
+	bpf.LoadMemShift{Off: 0},
+
+	// Check if UDP header destination port equals 68
+	bpf.LoadIndirect{Off: 2, Size: 2}, // Offset relative to header size in register X
+	bpf.JumpIf{Cond: bpf.JumpEqual, Val: 68, SkipTrue: 1},
+	bpf.RetConstant{Val: 0}, // Discard
+
+	// Accept packet and pass through up maximum IP packet size
+	bpf.RetConstant{Val: maxIPv4MTU},
+}
+
+var bpfFilter = mustAssemble(bpfFilterInstructions)
+
+// BroadcastTransport implements a DHCP transport based on a custom IP/UDP stack fulfilling the
+// specific requirements for broadcasting DHCP packets (like all-zero source address, no ARP, ...)
+type BroadcastTransport struct {
+	rawConn *raw.Conn
+	iface   *net.Interface
+}
+
+func NewBroadcastTransport(iface *net.Interface) *BroadcastTransport {
+	return &BroadcastTransport{iface: iface}
+}
+
+func (t *BroadcastTransport) Open() error {
+	if t.rawConn != nil {
+		return errors.New("broadcast transport already open")
+	}
+	rawConn, err := raw.ListenPacket(t.iface, uint16(layers.EthernetTypeIPv4), &raw.Config{
+		LinuxSockDGRAM: true,
+		Filter:         bpfFilter,
+	})
+	if err != nil {
+		return fmt.Errorf("failed to create raw listener: %w", err)
+	}
+	t.rawConn = rawConn
+	return nil
+}
+
+func (t *BroadcastTransport) Send(payload *dhcpv4.DHCPv4) error {
+	if t.rawConn == nil {
+		return errors.New("broadcast transport closed")
+	}
+	packet := gopacket.NewSerializeBuffer()
+	opts := gopacket.SerializeOptions{
+		ComputeChecksums: true,
+		FixLengths:       true,
+	}
+
+	ipLayer := &layers.IPv4{
+		Version:  4,
+		TOS:      dscpCS7 << 2, // Shift left of ECN field
+		TTL:      1,            // These packets should never be routed (their IP headers contain garbage)
+		Protocol: layers.IPProtocolUDP,
+		Flags:    layers.IPv4DontFragment, // Most DHCP servers don't support fragmented packets
+		DstIP:    net.IPv4bcast,
+		SrcIP:    net.IPv4zero,
+	}
+	udpLayer := &layers.UDP{
+		DstPort: 67,
+		SrcPort: 68,
+	}
+	if err := udpLayer.SetNetworkLayerForChecksum(ipLayer); err != nil {
+		panic("Invalid layer stackup encountered")
+	}
+
+	err := gopacket.SerializeLayers(packet, opts,
+		ipLayer,
+		udpLayer,
+		gopacket.Payload(payload.ToBytes()))
+
+	if err != nil {
+		return fmt.Errorf("failed to assemble packet: %w", err)
+	}
+
+	_, err = t.rawConn.WriteTo(packet.Bytes(), &raw.Addr{HardwareAddr: layers.EthernetBroadcast})
+	if err != nil {
+		return fmt.Errorf("failed to transmit broadcast packet: %w", err)
+	}
+	return nil
+}
+
+func (t *BroadcastTransport) Receive() (*dhcpv4.DHCPv4, error) {
+	if t.rawConn == nil {
+		return nil, errors.New("broadcast transport closed")
+	}
+	buf := make([]byte, math.MaxUint16) // Maximum IP packet size
+	n, _, err := t.rawConn.ReadFrom(buf)
+	if err != nil {
+		return nil, deadlineFromTimeout(err)
+	}
+	respPacket := gopacket.NewPacket(buf[:n], layers.LayerTypeIPv4, gopacket.Default)
+	ipLayer := respPacket.Layer(layers.LayerTypeIPv4)
+	if ipLayer == nil {
+		return nil, NewInvalidMessageError(errors.New("got invalid IP packet"))
+	}
+	ip := ipLayer.(*layers.IPv4)
+	if ip.Flags&layers.IPv4MoreFragments != 0 {
+		return nil, NewInvalidMessageError(errors.New("got fragmented message"))
+	}
+
+	udpLayer := respPacket.Layer(layers.LayerTypeUDP)
+	if udpLayer == nil {
+		return nil, NewInvalidMessageError(errors.New("got non-UDP packet"))
+	}
+	udp := udpLayer.(*layers.UDP)
+	if udp.DstPort != 68 {
+		return nil, NewInvalidMessageError(errors.New("message not for DHCP client port"))
+	}
+	msg, err := dhcpv4.FromBytes(udp.Payload)
+	if err != nil {
+		return nil, NewInvalidMessageError(fmt.Errorf("failed to decode DHCPv4 message: %w", err))
+	}
+	return msg, nil
+}
+
+func (t *BroadcastTransport) Close() error {
+	if t.rawConn == nil {
+		return nil
+	}
+	if err := t.rawConn.Close(); err != nil {
+		return err
+	}
+	t.rawConn = nil
+	return nil
+}
+
+func (t *BroadcastTransport) SetReceiveDeadline(deadline time.Time) error {
+	if t.rawConn == nil {
+		return errors.New("broadcast transport closed")
+	}
+	return t.rawConn.SetReadDeadline(deadline)
+}
diff --git a/core/pkg/dhcp4c/transport/transport_unicast.go b/core/pkg/dhcp4c/transport/transport_unicast.go
new file mode 100644
index 0000000..bf2b3a4
--- /dev/null
+++ b/core/pkg/dhcp4c/transport/transport_unicast.go
@@ -0,0 +1,122 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package transport
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"net"
+	"os"
+	"strings"
+	"time"
+
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"golang.org/x/sys/unix"
+)
+
+// UnicastTransport implements a DHCP transport based on a normal Linux UDP socket with some custom
+// socket options to influence DSCP and routing.
+type UnicastTransport struct {
+	udpConn  *net.UDPConn
+	targetIP net.IP
+	iface    *net.Interface
+}
+
+func NewUnicastTransport(iface *net.Interface) *UnicastTransport {
+	return &UnicastTransport{
+		iface: iface,
+	}
+}
+
+func (t *UnicastTransport) Open(serverIP, bindIP net.IP) error {
+	if t.udpConn != nil {
+		return errors.New("unicast transport already open")
+	}
+	rawFd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0)
+	if err != nil {
+		return fmt.Errorf("failed to get socket: %w", err)
+	}
+	if err := unix.BindToDevice(rawFd, t.iface.Name); err != nil {
+		return fmt.Errorf("failed to bind UDP interface to device: %w", err)
+	}
+	if err := unix.SetsockoptByte(rawFd, unix.SOL_IP, unix.IP_TOS, dscpCS7<<2); err != nil {
+		return fmt.Errorf("failed to set DSCP CS7: %w", err)
+	}
+	var addr [4]byte
+	copy(addr[:], bindIP.To4())
+	if err := unix.Bind(rawFd, &unix.SockaddrInet4{Addr: addr, Port: 68}); err != nil {
+		return fmt.Errorf("failed to bind UDP unicast interface: %w", err)
+	}
+	filePtr := os.NewFile(uintptr(rawFd), "dhcp-udp")
+	defer filePtr.Close()
+	conn, err := net.FileConn(filePtr)
+	if err != nil {
+		return fmt.Errorf("failed to initialize runtime-supported UDP connection: %w", err)
+	}
+	realConn, ok := conn.(*net.UDPConn)
+	if !ok {
+		panic("UDP socket imported into Go runtime is no longer a UDP socket")
+	}
+	t.udpConn = realConn
+	t.targetIP = serverIP
+	return nil
+}
+
+func (t *UnicastTransport) Send(payload *dhcpv4.DHCPv4) error {
+	if t.udpConn == nil {
+		return errors.New("unicast transport closed")
+	}
+	_, _, err := t.udpConn.WriteMsgUDP(payload.ToBytes(), []byte{}, &net.UDPAddr{
+		IP:   t.targetIP,
+		Port: 67,
+	})
+	return err
+}
+
+func (t *UnicastTransport) SetReceiveDeadline(deadline time.Time) error {
+	return t.udpConn.SetReadDeadline(deadline)
+}
+
+func (t *UnicastTransport) Receive() (*dhcpv4.DHCPv4, error) {
+	if t.udpConn == nil {
+		return nil, errors.New("unicast transport closed")
+	}
+	receiveBuf := make([]byte, math.MaxUint16)
+	_, _, err := t.udpConn.ReadFromUDP(receiveBuf)
+	if err != nil {
+		return nil, deadlineFromTimeout(err)
+	}
+	msg, err := dhcpv4.FromBytes(receiveBuf)
+	if err != nil {
+		return nil, NewInvalidMessageError(err)
+	}
+	return msg, nil
+}
+
+func (t *UnicastTransport) Close() error {
+	if t.udpConn == nil {
+		return nil
+	}
+	err := t.udpConn.Close()
+	t.udpConn = nil
+	// TODO(lorenz): Move to net.ErrClosed once Go 1.16 lands
+	if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
+		return nil
+	}
+	return err
+}
