diff --git a/osbase/net/dhcp4c/BUILD.bazel b/osbase/net/dhcp4c/BUILD.bazel
new file mode 100644
index 0000000..af7081c
--- /dev/null
+++ b/osbase/net/dhcp4c/BUILD.bazel
@@ -0,0 +1,34 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "dhcp4c",
+    srcs = [
+        "dhcpc.go",
+        "doc.go",
+        "lease.go",
+    ],
+    importpath = "source.monogon.dev/osbase/net/dhcp4c",
+    visibility = ["//visibility:public"],
+    deps = [
+        "//osbase/net/dhcp4c/transport",
+        "//osbase/supervisor",
+        "@com_github_cenkalti_backoff_v4//:backoff",
+        "@com_github_insomniacslk_dhcp//dhcpv4",
+        "@com_github_insomniacslk_dhcp//iana",
+    ],
+)
+
+go_test(
+    name = "dhcp4c_test",
+    srcs = [
+        "dhcpc_test.go",
+        "lease_test.go",
+    ],
+    embed = [":dhcp4c"],
+    deps = [
+        "//osbase/net/dhcp4c/transport",
+        "@com_github_cenkalti_backoff_v4//:backoff",
+        "@com_github_insomniacslk_dhcp//dhcpv4",
+        "@com_github_stretchr_testify//assert",
+    ],
+)
diff --git a/osbase/net/dhcp4c/callback/BUILD.bazel b/osbase/net/dhcp4c/callback/BUILD.bazel
new file mode 100644
index 0000000..a8780fc
--- /dev/null
+++ b/osbase/net/dhcp4c/callback/BUILD.bazel
@@ -0,0 +1,33 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
+
+go_library(
+    name = "callback",
+    srcs = ["callback.go"],
+    importpath = "source.monogon.dev/osbase/net/dhcp4c/callback",
+    visibility = ["//visibility:public"],
+    deps = [
+        "//osbase/net/dhcp4c",
+        "@com_github_insomniacslk_dhcp//dhcpv4",
+        "@com_github_vishvananda_netlink//:netlink",
+        "@org_golang_x_sys//unix",
+    ],
+)
+
+go_test(
+    name = "callback_test",
+    srcs = ["callback_test.go"],
+    embed = [":callback"],
+    deps = [
+        "//osbase/net/dhcp4c",
+        "@com_github_google_go_cmp//cmp",
+        "@com_github_insomniacslk_dhcp//dhcpv4",
+        "@com_github_vishvananda_netlink//:netlink",
+        "@org_golang_x_sys//unix",
+    ],
+)
+
+k_test(
+    name = "ktest",
+    tester = ":callback_test",
+)
diff --git a/osbase/net/dhcp4c/callback/callback.go b/osbase/net/dhcp4c/callback/callback.go
new file mode 100644
index 0000000..dc3088b
--- /dev/null
+++ b/osbase/net/dhcp4c/callback/callback.go
@@ -0,0 +1,159 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+// Package callback contains minimal callbacks for configuring the kernel with
+// options received over DHCP.
+//
+// These directly configure the relevant kernel subsytems and need to own
+// certain parts of them as documented on a per- callback basis to make sure
+// that they can recover from restarts and crashes of the DHCP client.
+// The callbacks in here are not suitable for use in advanced network scenarios
+// like running multiple DHCP clients per interface via ClientIdentifier or
+// when running an external FIB manager. In these cases it's advised to extract
+// the necessary information from the lease in your own callback and
+// communicate it directly to the responsible entity.
+package callback
+
+import (
+	"fmt"
+	"math"
+	"net"
+	"os"
+	"time"
+
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/vishvananda/netlink"
+	"golang.org/x/sys/unix"
+
+	"source.monogon.dev/osbase/net/dhcp4c"
+)
+
+// Compose can be used to chain multiple callbacks
+func Compose(callbacks ...dhcp4c.LeaseCallback) dhcp4c.LeaseCallback {
+	return func(lease *dhcp4c.Lease) error {
+		for _, cb := range callbacks {
+			if err := cb(lease); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+}
+
+func isIPNetEqual(a, b *net.IPNet) bool {
+	if a == b {
+		return true
+	}
+	if a == nil || b == nil {
+		return false
+	}
+	aOnes, aBits := a.Mask.Size()
+	bOnes, bBits := b.Mask.Size()
+	return a.IP.Equal(b.IP) && aOnes == bOnes && aBits == bBits
+}
+
+// ManageIP sets up and tears down the assigned IP address. It takes exclusive
+// ownership of all IPv4 addresses on the given interface which do not have
+// IFA_F_PERMANENT set, so it's not possible to run multiple dynamic addressing
+// clients on a single interface.
+func ManageIP(iface netlink.Link) dhcp4c.LeaseCallback {
+	return func(lease *dhcp4c.Lease) error {
+		newNet := lease.IPNet()
+
+		addrs, err := netlink.AddrList(iface, netlink.FAMILY_V4)
+		if err != nil {
+			return fmt.Errorf("netlink failed to list addresses: %w", err)
+		}
+
+		for _, addr := range addrs {
+			if addr.Flags&unix.IFA_F_PERMANENT == 0 {
+				// Linux identifies addreses by IP, mask and peer (see
+				// net/ipv4/devinet.find_matching_ifa in Linux 5.10).
+				// So don't touch addresses which match on these properties as
+				// AddrReplace will atomically reconfigure them anyways without
+				// interrupting things.
+				if isIPNetEqual(addr.IPNet, newNet) && addr.Peer == nil && lease != nil {
+					continue
+				}
+
+				if err := netlink.AddrDel(iface, &addr); !os.IsNotExist(err) && err != nil {
+					return fmt.Errorf("failed to delete address: %w", err)
+				}
+			}
+		}
+
+		if lease != nil {
+			remainingLifetimeSecs := int(math.Ceil(time.Until(lease.ExpiresAt).Seconds()))
+			newBroadcastIP := dhcpv4.GetIP(dhcpv4.OptionBroadcastAddress, lease.Options)
+			if err := netlink.AddrReplace(iface, &netlink.Addr{
+				IPNet:       newNet,
+				ValidLft:    remainingLifetimeSecs,
+				PreferedLft: remainingLifetimeSecs,
+				Broadcast:   newBroadcastIP,
+			}); err != nil {
+				return fmt.Errorf("failed to update address: %w", err)
+			}
+		}
+		return nil
+	}
+}
+
+// ManageRoutes installs and removes routes according to the current DHCP lease,
+// including the default route (if any).
+// It takes ownership of all RTPROTO_DHCP routes on the given interface, so it's
+// not possible to run multiple DHCP clients on the given interface.
+func ManageRoutes(iface netlink.Link) dhcp4c.LeaseCallback {
+	return func(lease *dhcp4c.Lease) error {
+		newRoutes := lease.Routes()
+
+		dhcpRoutes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{
+			Protocol:  unix.RTPROT_DHCP,
+			LinkIndex: iface.Attrs().Index,
+		}, netlink.RT_FILTER_OIF|netlink.RT_FILTER_PROTOCOL)
+		if err != nil {
+			return fmt.Errorf("netlink failed to list routes: %w", err)
+		}
+		for _, route := range dhcpRoutes {
+			// Don't remove routes which can be atomically replaced by
+			// RouteReplace to prevent potential traffic disruptions.
+			//
+			// This is O(n^2) but the number of routes is bounded by the size
+			// of a DHCP packet (around 100 routes). Sorting both would be
+			// be marginally faster for large amounts of routes only and in 99%
+			// of cases it's going to be <5 routes.
+			var found bool
+			for _, newRoute := range newRoutes {
+				if isIPNetEqual(newRoute.Dest, route.Dst) {
+					found = true
+					break
+				}
+			}
+			if !found {
+				err := netlink.RouteDel(&route)
+				if !os.IsNotExist(err) && err != nil {
+					return fmt.Errorf("failed to delete DHCP route: %w", err)
+				}
+			}
+		}
+
+		for _, route := range newRoutes {
+			newRoute := netlink.Route{
+				Protocol:  unix.RTPROT_DHCP,
+				Dst:       route.Dest,
+				Gw:        route.Router,
+				Src:       lease.AssignedIP,
+				LinkIndex: iface.Attrs().Index,
+				Scope:     netlink.SCOPE_UNIVERSE,
+			}
+			// Routes with a non-L3 gateway are link-scoped
+			if route.Router.IsUnspecified() {
+				newRoute.Scope = netlink.SCOPE_LINK
+			}
+			err := netlink.RouteReplace(&newRoute)
+			if err != nil {
+				return fmt.Errorf("failed to add %s: %w", route, err)
+			}
+		}
+		return nil
+	}
+}
diff --git a/osbase/net/dhcp4c/callback/callback_test.go b/osbase/net/dhcp4c/callback/callback_test.go
new file mode 100644
index 0000000..db616bb
--- /dev/null
+++ b/osbase/net/dhcp4c/callback/callback_test.go
@@ -0,0 +1,355 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package callback
+
+import (
+	"fmt"
+	"math"
+	"net"
+	"os"
+	"testing"
+	"time"
+
+	"github.com/google/go-cmp/cmp"
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/vishvananda/netlink"
+	"golang.org/x/sys/unix"
+
+	"source.monogon.dev/osbase/net/dhcp4c"
+)
+
+func trivialLeaseFromNet(ipnet net.IPNet) *dhcp4c.Lease {
+	opts := make(dhcpv4.Options)
+	opts.Update(dhcpv4.OptSubnetMask(ipnet.Mask))
+	return &dhcp4c.Lease{
+		AssignedIP: ipnet.IP,
+		ExpiresAt:  time.Now().Add(1 * time.Second),
+		Options:    opts,
+	}
+}
+
+var (
+	testNet1          = net.IPNet{IP: net.IP{10, 0, 1, 2}, Mask: net.CIDRMask(24, 32)}
+	testNet1Broadcast = net.IP{10, 0, 1, 255}
+	testNet1Router    = net.IP{10, 0, 1, 1}
+	testNet2          = net.IPNet{IP: net.IP{10, 0, 2, 2}, Mask: net.CIDRMask(24, 32)}
+	testNet2Broadcast = net.IP{10, 0, 2, 255}
+	testNet2Router    = net.IP{10, 0, 2, 1}
+	mainRoutingTable  = 254 // Linux automatically puts all routes into this table unless specified
+)
+
+func TestAssignedIPCallback(t *testing.T) {
+	if os.Getenv("IN_KTEST") != "true" {
+		t.Skip("Not in ktest")
+	}
+
+	var tests = []struct {
+		name          string
+		initialAddrs  []netlink.Addr
+		newLease      *dhcp4c.Lease
+		expectedAddrs []netlink.Addr
+	}{
+		// Lifetimes are necessary, otherwise the Kernel sets the
+		// IFA_F_PERMANENT flag behind our back.
+		{
+			name:          "RemoveOldIPs",
+			initialAddrs:  []netlink.Addr{{IPNet: &testNet1, ValidLft: 60}, {IPNet: &testNet2, ValidLft: 60}},
+			newLease:      nil,
+			expectedAddrs: nil,
+		},
+		{
+			name:         "IgnoresPermanentIPs",
+			initialAddrs: []netlink.Addr{{IPNet: &testNet1, Flags: unix.IFA_F_PERMANENT}, {IPNet: &testNet2, ValidLft: 60}},
+			newLease:     trivialLeaseFromNet(testNet2),
+			expectedAddrs: []netlink.Addr{
+				{IPNet: &testNet1, Flags: unix.IFA_F_PERMANENT, ValidLft: math.MaxUint32, PreferedLft: math.MaxUint32, Broadcast: testNet1Broadcast},
+				{IPNet: &testNet2, ValidLft: 1, PreferedLft: 1, Broadcast: testNet2Broadcast},
+			},
+		},
+		{
+			name:         "AssignsNewIP",
+			initialAddrs: []netlink.Addr{},
+			newLease:     trivialLeaseFromNet(testNet2),
+			expectedAddrs: []netlink.Addr{
+				{IPNet: &testNet2, ValidLft: 1, PreferedLft: 1, Broadcast: testNet2Broadcast},
+			},
+		},
+		{
+			name:         "UpdatesIP",
+			initialAddrs: []netlink.Addr{},
+			newLease:     trivialLeaseFromNet(testNet1),
+			expectedAddrs: []netlink.Addr{
+				{IPNet: &testNet1, ValidLft: 1, PreferedLft: 1, Broadcast: testNet1Broadcast},
+			},
+		},
+		{
+			name:          "RemovesIPOnRelease",
+			initialAddrs:  []netlink.Addr{{IPNet: &testNet1, ValidLft: 60, PreferedLft: 60}},
+			newLease:      nil,
+			expectedAddrs: nil,
+		},
+	}
+	for i, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			testLink := &netlink.Dummy{
+				LinkAttrs: netlink.LinkAttrs{
+					Name:  fmt.Sprintf("aipcb-test-%d", i),
+					Flags: unix.IFF_UP,
+				},
+			}
+			if err := netlink.LinkAdd(testLink); err != nil {
+				t.Fatalf("test cannot set up network interface: %v", err)
+			}
+			defer netlink.LinkDel(testLink)
+			for _, addr := range test.initialAddrs {
+				if err := netlink.AddrAdd(testLink, &addr); err != nil {
+					t.Fatalf("test cannot set up initial addrs: %v", err)
+				}
+			}
+			// Associate dynamically-generated interface name for later comparison
+			for i := range test.expectedAddrs {
+				test.expectedAddrs[i].Label = testLink.Name
+				test.expectedAddrs[i].LinkIndex = testLink.Index
+			}
+			cb := ManageIP(testLink)
+			if err := cb(test.newLease); err != nil {
+				t.Fatalf("callback returned an error: %v", err)
+			}
+			addrs, err := netlink.AddrList(testLink, netlink.FAMILY_V4)
+			if err != nil {
+				t.Fatalf("test cannot read back addrs from interface: %v", err)
+			}
+			if diff := cmp.Diff(test.expectedAddrs, addrs); diff != "" {
+				t.Errorf("Wrong IPs on interface (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func leaseAddRouter(lease *dhcp4c.Lease, router net.IP) *dhcp4c.Lease {
+	lease.Options.Update(dhcpv4.OptRouter(router))
+	return lease
+}
+
+func leaseAddClasslessRoutes(lease *dhcp4c.Lease, routes ...*dhcpv4.Route) *dhcp4c.Lease {
+	lease.Options.Update(dhcpv4.OptClasslessStaticRoute(routes...))
+	return lease
+}
+
+func mustParseCIDR(cidr string) *net.IPNet {
+	_, n, err := net.ParseCIDR(cidr)
+	if err != nil {
+		panic(err)
+	}
+	// Equality checks don't know about net.IP's canonicalization rules.
+	if n.IP.To4() != nil {
+		n.IP = n.IP.To4()
+	}
+	return n
+}
+
+func TestDefaultRouteCallback(t *testing.T) {
+	if os.Getenv("IN_KTEST") != "true" {
+		t.Skip("Not in ktest")
+	}
+	// testRoute is only used as a route destination and not configured on any
+	// interface.
+	testRoute := net.IPNet{IP: net.IP{10, 0, 3, 0}, Mask: net.CIDRMask(24, 32)}
+
+	// A test interface is set up for each test and assigned testNet1 and
+	// testNet2 so that testNet1Router and testNet2Router are valid gateways
+	// for routes in this environment. A LinkIndex of -1 is replaced by the
+	// correct link index for this test interface at runtime for both
+	// initialRoutes and expectedRoutes.
+	var tests = []struct {
+		name           string
+		initialRoutes  []netlink.Route
+		newLease       *dhcp4c.Lease
+		expectedRoutes []netlink.Route
+	}{
+		{
+			name:          "AddsDefaultRoute",
+			initialRoutes: []netlink.Route{},
+			newLease:      leaseAddRouter(trivialLeaseFromNet(testNet1), testNet1Router),
+			expectedRoutes: []netlink.Route{{
+				Protocol:  unix.RTPROT_DHCP,
+				Dst:       mustParseCIDR("0.0.0.0/0"),
+				Family:    unix.AF_INET,
+				Gw:        testNet1Router,
+				Src:       testNet1.IP,
+				Table:     mainRoutingTable,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Type:      unix.RTN_UNICAST,
+			}},
+		},
+		{
+			name:           "IgnoresLeasesWithoutRouter",
+			initialRoutes:  []netlink.Route{},
+			newLease:       trivialLeaseFromNet(testNet1),
+			expectedRoutes: nil,
+		},
+		{
+			name: "RemovesUnrelatedOldRoutes",
+			initialRoutes: []netlink.Route{{
+				Dst:       &testRoute,
+				Family:    unix.AF_INET,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Protocol:  unix.RTPROT_DHCP,
+				Gw:        testNet2Router,
+				Scope:     netlink.SCOPE_UNIVERSE,
+			}},
+			newLease:       nil,
+			expectedRoutes: nil,
+		},
+		{
+			name: "IgnoresNonDHCPRoutes",
+			initialRoutes: []netlink.Route{{
+				Dst:       &testRoute,
+				Family:    unix.AF_INET,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Protocol:  unix.RTPROT_BIRD,
+				Gw:        testNet2Router,
+			}},
+			newLease: nil,
+			expectedRoutes: []netlink.Route{{
+				Protocol:  unix.RTPROT_BIRD,
+				Dst:       &testRoute,
+				Family:    unix.AF_INET,
+				Gw:        testNet2Router,
+				Table:     mainRoutingTable,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Type:      unix.RTN_UNICAST,
+			}},
+		},
+		{
+			name: "RemovesRoute",
+			initialRoutes: []netlink.Route{{
+				Dst:       nil,
+				Family:    unix.AF_INET,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Protocol:  unix.RTPROT_DHCP,
+				Gw:        testNet2Router,
+			}},
+			newLease:       nil,
+			expectedRoutes: nil,
+		},
+		{
+			name: "UpdatesRoute",
+			initialRoutes: []netlink.Route{{
+				Dst:       nil,
+				Family:    unix.AF_INET,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Protocol:  unix.RTPROT_DHCP,
+				Src:       testNet1.IP,
+				Gw:        testNet1Router,
+			}},
+			newLease: leaseAddRouter(trivialLeaseFromNet(testNet2), testNet2Router),
+			expectedRoutes: []netlink.Route{{
+				Protocol:  unix.RTPROT_DHCP,
+				Dst:       mustParseCIDR("0.0.0.0/0"),
+				Family:    unix.AF_INET,
+				Gw:        testNet2Router,
+				Src:       testNet2.IP,
+				Table:     mainRoutingTable,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Type:      unix.RTN_UNICAST,
+			}},
+		},
+		{
+			name:          "AddsClasslessStaticRoutes",
+			initialRoutes: []netlink.Route{},
+			newLease: leaseAddClasslessRoutes(
+				// Router should be ignored
+				leaseAddRouter(trivialLeaseFromNet(testNet1), testNet1Router),
+				// P2P/foreign gateway route
+				&dhcpv4.Route{Dest: mustParseCIDR("192.168.42.1/32"), Router: net.IPv4zero},
+				// Standard route over foreign gateway set up by previous route
+				&dhcpv4.Route{Dest: mustParseCIDR("0.0.0.0/0"), Router: net.IPv4(192, 168, 42, 1)},
+			),
+			expectedRoutes: []netlink.Route{{
+				Protocol:  unix.RTPROT_DHCP,
+				Dst:       mustParseCIDR("0.0.0.0/0"),
+				Family:    unix.AF_INET,
+				Gw:        net.IPv4(192, 168, 42, 1).To4(), // Equal() doesn't know about canonicalization
+				Src:       testNet1.IP,
+				Table:     mainRoutingTable,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Type:      unix.RTN_UNICAST,
+			}, {
+				Protocol:  unix.RTPROT_DHCP,
+				Dst:       mustParseCIDR("192.168.42.1/32"),
+				Family:    unix.AF_INET,
+				Gw:        nil,
+				Src:       testNet1.IP,
+				Table:     mainRoutingTable,
+				LinkIndex: -1, // Filled in dynamically with test interface
+				Type:      unix.RTN_UNICAST,
+				Scope:     unix.RT_SCOPE_LINK,
+			}},
+		},
+	}
+	for i, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			testLink := &netlink.Dummy{
+				LinkAttrs: netlink.LinkAttrs{
+					Name:  fmt.Sprintf("drcb-test-%d", i),
+					Flags: unix.IFF_UP,
+				},
+			}
+			if err := netlink.LinkAdd(testLink); err != nil {
+				t.Fatalf("test cannot set up network interface: %v", err)
+			}
+			defer func() { // Clean up after each test
+				routes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{}, 0)
+				if err == nil {
+					for _, route := range routes {
+						netlink.RouteDel(&route)
+					}
+				}
+			}()
+			defer netlink.LinkDel(testLink)
+			if err := netlink.AddrAdd(testLink, &netlink.Addr{
+				IPNet: &testNet1,
+			}); err != nil {
+				t.Fatalf("test cannot set up test addrs: %v", err)
+			}
+			if err := netlink.AddrAdd(testLink, &netlink.Addr{
+				IPNet: &testNet2,
+			}); err != nil {
+				t.Fatalf("test cannot set up test addrs: %v", err)
+			}
+			for _, route := range test.initialRoutes {
+				if route.LinkIndex == -1 {
+					route.LinkIndex = testLink.Index
+				}
+				if err := netlink.RouteAdd(&route); err != nil {
+					t.Fatalf("test cannot set up initial routes: %v", err)
+				}
+			}
+			for i := range test.expectedRoutes {
+				if test.expectedRoutes[i].LinkIndex == -1 {
+					test.expectedRoutes[i].LinkIndex = testLink.Index
+				}
+			}
+
+			cb := ManageRoutes(testLink)
+			if err := cb(test.newLease); err != nil {
+				t.Fatalf("callback returned an error: %v", err)
+			}
+			routes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{}, 0)
+			if err != nil {
+				t.Fatalf("test cannot read back routes: %v", err)
+			}
+			var notKernelRoutes []netlink.Route
+			for _, route := range routes {
+				if route.Protocol != unix.RTPROT_KERNEL { // Filter kernel-managed routes
+					notKernelRoutes = append(notKernelRoutes, route)
+				}
+			}
+			if diff := cmp.Diff(test.expectedRoutes, notKernelRoutes); diff != "" {
+				t.Errorf("Expected route mismatch (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
diff --git a/osbase/net/dhcp4c/dhcpc.go b/osbase/net/dhcp4c/dhcpc.go
new file mode 100644
index 0000000..ad4c9dd
--- /dev/null
+++ b/osbase/net/dhcp4c/dhcpc.go
@@ -0,0 +1,709 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+// 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"
+
+	"source.monogon.dev/osbase/net/dhcp4c/transport"
+	"source.monogon.dev/osbase/supervisor"
+)
+
+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 ErrDeadlineExceeded
+	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
+	// ErrDeadlineExceeded. 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(*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
+
+	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
+}
+
+// defaultBackoffOpts can be passed to NewExponentialBackOff and configures it
+// to retry infinitely and use a DHCP-appropriate InitialInterval.
+func defaultBackoffOpts(b *backoff.ExponentialBackOff) {
+	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
+}
+
+// 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 := backoff.NewExponentialBackOff(defaultBackoffOpts)
+
+	acceptOfferBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts,
+		// Abort after 30s and go back to discovering
+		backoff.WithMaxElapsedTime(30*time.Second))
+
+	renewBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts,
+		// Increase maximum interval to reduce chatter when the server is down
+		backoff.WithMaxInterval(5*time.Minute))
+
+	rebindBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts,
+		// Increase maximum interval to reduce chatter when the server is down
+		backoff.WithMaxInterval(5*time.Minute))
+
+	// Check if the hardware address contains at least one non-zero value.
+	// This exists to catch undefined/non-supplied hardware address values,
+	// it does not check for L2 protocol-specific hardware address constraints.
+	hasValidHWAddr := false
+	for _, b := range iface.HardwareAddr {
+		if b != 0x00 {
+			hasValidHWAddr = true
+			break
+		}
+	}
+	if !hasValidHWAddr {
+		return nil, fmt.Errorf("iface HardwareAddr is invalid (only zeroes or invalid length): %x", iface.HardwareAddr)
+	}
+
+	return &Client{
+		state:              stateDiscovering,
+		broadcastConn:      broadcastConn,
+		unicastConn:        transport.NewUnicastTransport(iface),
+		iface:              iface,
+		RequestedOptions:   dhcpv4.OptionCodeList{},
+		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(append(dhcpv4.OptionCodeList(nil), 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 s.stateDeadline.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.ErrDeadlineExceeded) {
+			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, ErrInvalidMsg) {
+			return err
+		}
+	}
+}
+
+var ErrInvalidMsg = 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 ErrInvalidMsg
+			},
+		})
+	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 ErrInvalidMsg
+			},
+			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 ErrInvalidMsg
+			},
+			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 ErrInvalidMsg
+			},
+			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(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.lease = nil
+	c.DiscoverBackoff.Reset()
+	if err := c.LeaseCallback(nil); err != nil {
+		return fmt.Errorf("lease callback failed: %w", err)
+	}
+	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)
+	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(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/osbase/net/dhcp4c/dhcpc_test.go b/osbase/net/dhcp4c/dhcpc_test.go
new file mode 100644
index 0000000..67651a7
--- /dev/null
+++ b/osbase/net/dhcp4c/dhcpc_test.go
@@ -0,0 +1,501 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package dhcp4c
+
+import (
+	"context"
+	"fmt"
+	"net"
+	"testing"
+	"time"
+
+	"github.com/cenkalti/backoff/v4"
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/stretchr/testify/assert"
+
+	"source.monogon.dev/osbase/net/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.ErrDeadlineExceeded
+}
+
+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) {
+	var 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.Fatal(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(lease *Lease) error {
+		assert.Equal(t, testIP, lease.AssignedIP, "new lease has wrong IP")
+		return nil
+	}
+
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Fatal(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.Fatal(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(lease *Lease) error {
+		assert.Equal(t, testIP, lease.AssignedIP, "callback called with wrong IP")
+		assert.Equal(t, p.ft.Now().Add(leaseTime), lease.ExpiresAt, "invalid ExpiresAt")
+		return nil
+	}
+	p.bmt.sendPackets(offer)
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Fatal(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.Fatal(err)
+	}
+	// We cannot intercept time.After so we just advance the clock by the time slept
+	p.ft.Advance(5 * time.Millisecond)
+	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(lease *Lease) error {
+		assert.Equal(t, testIP, lease.AssignedIP, "callback called with wrong IP")
+		assert.Equal(t, p.ft.Now().Add(leaseTime), lease.ExpiresAt, "invalid ExpiresAt")
+		assert.Equal(t, []byte{0x12}, lease.Options.Get(TestOption(1)), "renewal didn't add new option")
+		return nil
+	}
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Fatal(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(*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.Fatal(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.Fatal(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(lease *Lease) error {
+		assert.Equal(t, testIP, lease.AssignedIP, "callback called with wrong IP")
+		assert.Equal(t, p.ft.Now().Add(leaseTime), lease.ExpiresAt, "invalid ExpiresAt")
+		assert.Equal(t, []byte{0x12}, lease.Options.Get(TestOption(1)), "renewal didn't add new option")
+		return nil
+	}
+	if err := p.c.runState(context.Background()); err != nil {
+		t.Fatal(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(lease *Lease) error {
+		assert.Nil(t, lease, "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.Fatal(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/osbase/net/dhcp4c/doc.go b/osbase/net/dhcp4c/doc.go
new file mode 100644
index 0000000..622452b
--- /dev/null
+++ b/osbase/net/dhcp4c/doc.go
@@ -0,0 +1,55 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+// 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/osbase/net/dhcp4c/lease.go b/osbase/net/dhcp4c/lease.go
new file mode 100644
index 0000000..fefe092
--- /dev/null
+++ b/osbase/net/dhcp4c/lease.go
@@ -0,0 +1,229 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package dhcp4c
+
+import (
+	"encoding/binary"
+	"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 given mask is not valid, use the default mask.
+	if _, bits := mask.Size(); bits != 32 {
+		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(),
+	}
+}
+
+// Routes returns all routes assigned by a DHCP answer. It combines and
+// normalizes data from the Router, StaticRoutingTable and ClasslessStaticRoute
+// options.
+func (l *Lease) Routes() []*dhcpv4.Route {
+	if l == nil {
+		return nil
+	}
+
+	// Note that this is different from l.IPNet() because we care about the
+	// network base address of the network instead of the assigned IP.
+	assignedNet := &net.IPNet{IP: l.AssignedIP.Mask(l.SubnetMask()), Mask: l.SubnetMask()}
+
+	// RFC 3442 Section DHCP Client Behavior:
+	// If the DHCP server returns both a Classless Static Routes option and
+	// a Router option, the DHCP client MUST ignore the Router option.
+	// Similarly, if the DHCP server returns both a Classless Static Routes
+	// option and a Static Routes option, the DHCP client MUST ignore the
+	// Static Routes option.
+	var routes dhcpv4.Routes
+	rawCIDRRoutes := l.Options.Get(dhcpv4.OptionClasslessStaticRoute)
+	if rawCIDRRoutes != nil {
+		// TODO(#96): This needs a logging story
+		// Ignore errors intentionally and just return what has been parsed
+		_ = routes.FromBytes(rawCIDRRoutes)
+		return sanitizeRoutes(routes, assignedNet)
+	}
+	// The Static Routes option contains legacy classful routes (i.e. routes
+	// whose mask is determined by the IP of the network).
+	// Each static route is expressed as a pair of IPs, the first one being
+	// the destination network and the second one being the router IP.
+	// See RFC 2132 Section 5.8 for further details.
+	legacyRouteIPs := dhcpv4.GetIPs(dhcpv4.OptionStaticRoutingTable, l.Options)
+	// Routes are only valid in pairs, cut the last one off if necessary
+	if len(legacyRouteIPs)%2 != 0 {
+		legacyRouteIPs = legacyRouteIPs[:len(legacyRouteIPs)-1]
+	}
+	for i := 0; i < len(legacyRouteIPs)/2; i++ {
+		dest := legacyRouteIPs[i*2]
+		if dest.IsUnspecified() {
+			// RFC 2132 Section 5.8:
+			// The default route (0.0.0.0) is an illegal destination for a
+			// static route.
+			continue
+		}
+		via := legacyRouteIPs[i*2+1]
+		destNet := net.IPNet{
+			// Apply the default mask just to make sure this is a valid route
+			IP:   dest.Mask(dest.DefaultMask()),
+			Mask: dest.DefaultMask(),
+		}
+		routes = append(routes, &dhcpv4.Route{Dest: &destNet, Router: via})
+	}
+	for _, r := range dhcpv4.GetIPs(dhcpv4.OptionRouter, l.Options) {
+		if r.IsGlobalUnicast() || r.IsLinkLocalUnicast() {
+			routes = append(routes, &dhcpv4.Route{
+				Dest:   &net.IPNet{IP: net.IPv4zero, Mask: net.IPv4Mask(0, 0, 0, 0)},
+				Router: r,
+			})
+			// Only one default router can exist, exit after the first one
+			break
+		}
+	}
+	return sanitizeRoutes(routes, assignedNet)
+}
+
+// sanitizeRoutes filters the list of routes by removing routes that are
+// obviously invalid. It filters out routes according to the following criteria:
+//  1. The route is not an interface route and its router is not a unicast or
+//     link-local address.
+//  2. Each route's router must be reachable according to the routes listed
+//     before it and the assigned network.
+//  3. The network mask must consist of all-ones followed by all-zeros. Non-
+//     contiguous routes are not allowed.
+//  4. If multiple routes match the same destination, only the first one is kept.
+//  5. Routes covering the loopback IP space (127.0.0.0/8) will be ignored if
+//     they are smaller than a /9 to prevent them from interfering with loopback
+//     IPs.
+func sanitizeRoutes(routes []*dhcpv4.Route, assignedNet *net.IPNet) []*dhcpv4.Route {
+	var saneRoutes []*dhcpv4.Route
+	for _, route := range routes {
+		if route.Router != nil && !route.Router.IsUnspecified() {
+			if !route.Router.IsGlobalUnicast() && !route.Router.IsLinkLocalUnicast() {
+				// Ignore non-unicast routers
+				continue
+			}
+			reachable := false
+			for _, r := range saneRoutes {
+				if r.Dest.Contains(route.Router) {
+					reachable = true
+					break
+				}
+			}
+			if assignedNet.Contains(route.Router) {
+				reachable = true
+			}
+			if !reachable {
+				continue
+			}
+		}
+		ones, bits := route.Dest.Mask.Size()
+		if bits == 0 && len(route.Dest.Mask) > 0 {
+			// Bitmask is not ones followed by zeros, i.e. invalid
+			continue
+		}
+		// Ignore routes that would be able to redirect loopback IPs
+		if route.Dest.IP.IsLoopback() && ones >= 8 {
+			continue
+		}
+		// Ignore routes that would shadow the implicit interface route
+		assignedOnes, _ := assignedNet.Mask.Size()
+		if assignedNet.IP.Equal(route.Dest.IP) && assignedOnes == ones {
+			continue
+		}
+		validDest := true
+		for _, r := range saneRoutes {
+			rOnes, _ := r.Dest.Mask.Size()
+			if r.Dest.IP.Equal(route.Dest.IP) && ones == rOnes {
+				// Exact duplicate, ignore
+				validDest = false
+				break
+			}
+		}
+		if validDest {
+			saneRoutes = append(saneRoutes, route)
+		}
+	}
+	return saneRoutes
+}
+
+// DNSServers represents an ordered collection of DNS servers
+type DNSServers []net.IP
+
+func (a DNSServers) Equal(b DNSServers) bool {
+	if len(a) == len(b) {
+		if len(a) == 0 {
+			return true // both are empty or nil
+		}
+		for i, aVal := range a {
+			if !aVal.Equal(b[i]) {
+				return false
+			}
+		}
+		return true
+	}
+	return false
+
+}
+
+func ip4toInt(ip net.IP) uint32 {
+	ip4 := ip.To4()
+	if ip4 == nil {
+		return 0
+	}
+	return binary.BigEndian.Uint32(ip4)
+}
+
+// DNSServers returns all unique valid DNS servers from the DHCP
+// DomainNameServers options.
+// It returns nil if the lease is nil.
+func (l *Lease) DNSServers() DNSServers {
+	if l == nil {
+		return nil
+	}
+	rawServers := dhcpv4.GetIPs(dhcpv4.OptionDomainNameServer, l.Options)
+	var servers DNSServers
+	serversSeenMap := make(map[uint32]bool)
+	for _, s := range rawServers {
+		ip4Num := ip4toInt(s)
+		if s.IsGlobalUnicast() || s.IsLinkLocalUnicast() {
+			if serversSeenMap[ip4Num] {
+				continue
+			}
+			serversSeenMap[ip4Num] = true
+			servers = append(servers, s)
+		}
+	}
+	return servers
+}
diff --git a/osbase/net/dhcp4c/lease_test.go b/osbase/net/dhcp4c/lease_test.go
new file mode 100644
index 0000000..5d233df
--- /dev/null
+++ b/osbase/net/dhcp4c/lease_test.go
@@ -0,0 +1,156 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package dhcp4c
+
+import (
+	"bytes"
+	"net"
+	"testing"
+
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestLeaseDHCPServers(t *testing.T) {
+	var tests = []struct {
+		name     string
+		lease    *Lease
+		expected DNSServers
+	}{{
+		name:     "ReturnsNilWithNoLease",
+		lease:    nil,
+		expected: nil,
+	}, {
+		name: "DiscardsInvalidIPs",
+		lease: &Lease{
+			Options: dhcpv4.OptionsFromList(dhcpv4.OptDNS(net.IP{0, 0, 0, 0})),
+		},
+		expected: nil,
+	}, {
+		name: "DeduplicatesIPs",
+		lease: &Lease{
+			Options: dhcpv4.OptionsFromList(dhcpv4.OptDNS(net.IP{192, 0, 2, 1}, net.IP{192, 0, 2, 2}, net.IP{192, 0, 2, 1})),
+		},
+		expected: DNSServers{net.IP{192, 0, 2, 1}, net.IP{192, 0, 2, 2}},
+	}}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			res := test.lease.DNSServers()
+			assert.Equal(t, test.expected, res)
+		})
+	}
+}
+
+func makeIPNet(cidr string) *net.IPNet {
+	_, n, err := net.ParseCIDR(cidr)
+	if err != nil {
+		panic(err)
+	}
+	return n
+}
+
+type testRoute struct {
+	dest     string
+	via      string
+	expected bool
+}
+
+func (t testRoute) toRealRoute() *dhcpv4.Route {
+	ip, n, err := net.ParseCIDR(t.dest)
+	if err != nil {
+		panic(err)
+	}
+	if !ip.Equal(n.IP) {
+		panic("testRoute is not aligned to route boundary")
+	}
+	routerIP := net.ParseIP(t.via)
+	if routerIP == nil && t.via != "" {
+		panic("routerIP is not valid")
+	}
+	return &dhcpv4.Route{
+		Dest:   n,
+		Router: routerIP,
+	}
+}
+
+func TestSanitizeRoutes(t *testing.T) {
+	var tests = []struct {
+		name        string
+		assignedNet *net.IPNet
+		routes      []testRoute
+	}{{
+		name:        "SimpleAdditionalRoute",
+		assignedNet: makeIPNet("10.0.5.0/24"),
+		routes: []testRoute{
+			{"10.0.7.0/24", "10.0.5.1", true},
+		},
+	}, {
+		name:        "OutOfNetworkGateway",
+		assignedNet: makeIPNet("10.5.0.2/32"),
+		routes: []testRoute{
+			{"10.0.7.1/32", "", true},
+			{"0.0.0.0/0", "10.0.7.1", true},
+		},
+	}, {
+		name:        "InvalidRouter",
+		assignedNet: makeIPNet("10.0.5.0/24"),
+		routes: []testRoute{
+			// Router is localhost
+			{"10.0.7.0/24", "127.0.0.1", false},
+			// Router is unreachable
+			{"10.0.8.0/24", "10.254.0.1", false},
+		},
+	}, {
+		name:        "SameDestinationRoutes",
+		assignedNet: makeIPNet("10.0.5.0/24"),
+		routes: []testRoute{
+			{"0.0.0.0/0", "10.0.5.1", true},
+			{"10.0.7.0/24", "10.0.5.1", true},
+			{"0.0.0.0/0", "10.0.7.1", false},
+		},
+	}, {
+		name:        "RoutesShadowingLoopback",
+		assignedNet: makeIPNet("10.0.5.0/24"),
+		routes: []testRoute{
+			// Default route, technically covers 127.0.0.0/8, but less-specific
+			{"0.0.0.0/0", "10.0.5.1", true},
+			// 127.0.0.0/8 is still more-specific
+			{"126.0.0.0/7", "10.0.5.1", true},
+			// Duplicate of 127.0.0.0/8, behavior undefined, disallowed
+			{"127.0.0.0/8", "10.0.5.1", false},
+			// Shadows localhost, disallowed
+			{"127.0.0.1/32", "10.0.5.1", false},
+		},
+	}}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			var routes []*dhcpv4.Route
+			var expectedRoutes []*dhcpv4.Route
+			for _, r := range test.routes {
+				routes = append(routes, r.toRealRoute())
+				if r.expected {
+					expectedRoutes = append(expectedRoutes, r.toRealRoute())
+				}
+			}
+			out := sanitizeRoutes(routes, test.assignedNet)
+			if len(out) != len(expectedRoutes) {
+				t.Errorf("expected %d routes, got %d", len(expectedRoutes), len(out))
+				t.Error("Expected:")
+				for _, r := range expectedRoutes {
+					t.Errorf("\t%s via %s", r.Dest, r.Router)
+				}
+				t.Error("Actual:")
+				for _, r := range out {
+					t.Errorf("\t%s via %s", r.Dest, r.Router)
+				}
+				return
+			}
+			for i, r := range expectedRoutes {
+				if !out[i].Router.Equal(r.Router) || !out[i].Dest.IP.Equal(r.Dest.IP) || !bytes.Equal(out[i].Dest.Mask, r.Dest.Mask) {
+					t.Errorf("expected %s via %s, got %s via %s", r.Dest, r.Router, out[i].Dest, out[i].Router)
+				}
+			}
+		})
+	}
+}
diff --git a/osbase/net/dhcp4c/transport/BUILD.bazel b/osbase/net/dhcp4c/transport/BUILD.bazel
new file mode 100644
index 0000000..8ba0830
--- /dev/null
+++ b/osbase/net/dhcp4c/transport/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "transport",
+    srcs = [
+        "transport.go",
+        "transport_broadcast.go",
+        "transport_unicast.go",
+    ],
+    importpath = "source.monogon.dev/osbase/net/dhcp4c/transport",
+    visibility = ["//osbase/net/dhcp4c:__subpackages__"],
+    deps = [
+        "@com_github_google_gopacket//:gopacket",
+        "@com_github_google_gopacket//layers",
+        "@com_github_insomniacslk_dhcp//dhcpv4",
+        "@com_github_mdlayher_packet//:packet",
+        "@org_golang_x_net//bpf",
+        "@org_golang_x_sys//unix",
+    ],
+)
diff --git a/osbase/net/dhcp4c/transport/transport.go b/osbase/net/dhcp4c/transport/transport.go
new file mode 100644
index 0000000..9a5ff14
--- /dev/null
+++ b/osbase/net/dhcp4c/transport/transport.go
@@ -0,0 +1,38 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+// Package transport contains Linux-based transports for the DHCP broadcast and
+// unicast specifications.
+package transport
+
+import (
+	"errors"
+	"fmt"
+	"net"
+)
+
+var ErrDeadlineExceeded = 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 {
+	var timeoutErr net.Error
+	if errors.As(err, &timeoutErr) && timeoutErr.Timeout() {
+		return ErrDeadlineExceeded
+	}
+	return err
+}
diff --git a/osbase/net/dhcp4c/transport/transport_broadcast.go b/osbase/net/dhcp4c/transport/transport_broadcast.go
new file mode 100644
index 0000000..b61af80
--- /dev/null
+++ b/osbase/net/dhcp4c/transport/transport_broadcast.go
@@ -0,0 +1,199 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+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/packet"
+	"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 *packet.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 := packet.Listen(t.iface, packet.Datagram, int(layers.EthernetTypeIPv4), &packet.Config{
+		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")
+	}
+	pkt := gopacket.NewSerializeBuffer()
+	opts := gopacket.SerializeOptions{
+		ComputeChecksums: true,
+		FixLengths:       true,
+	}
+
+	ipLayer := &layers.IPv4{
+		Version: 4,
+		// Shift left of ECN field
+		TOS: dscpCS7 << 2,
+		// These packets should never be routed (their IP headers contain
+		// garbage)
+		TTL:      1,
+		Protocol: layers.IPProtocolUDP,
+		// Most DHCP servers don't support fragmented packets.
+		Flags: layers.IPv4DontFragment,
+		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(pkt, opts,
+		ipLayer,
+		udpLayer,
+		gopacket.Payload(payload.ToBytes()))
+
+	if err != nil {
+		return fmt.Errorf("failed to assemble packet: %w", err)
+	}
+
+	_, err = t.rawConn.WriteTo(pkt.Bytes(), &packet.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/osbase/net/dhcp4c/transport/transport_unicast.go b/osbase/net/dhcp4c/transport/transport_unicast.go
new file mode 100644
index 0000000..b76e37c
--- /dev/null
+++ b/osbase/net/dhcp4c/transport/transport_unicast.go
@@ -0,0 +1,108 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package transport
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"net"
+	"os"
+	"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
+	if err != nil && errors.Is(err, net.ErrClosed) {
+		//nolint:returnerrcheck
+		return nil
+	}
+	return err
+}
