dhcpsvc

package
v0.107.72 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2026 License: GPL-3.0 Imports: 28 Imported by: 0

Documentation

Overview

Package dhcpsvc contains the AdGuard Home DHCP service.

TODO(e.burkov): Add tests.

Index

Constants

View Source
const (
	// IPv4DefaultTTL is the default Time to Live value in seconds as
	// recommended by RFC 1700.
	IPv4DefaultTTL = 64

	// IPProtoVersion is the IP internetwork general protocol version number as
	// defined by RFC 1700.
	IPProtoVersion = 4
)
View Source
const (
	// ServerPortV4 is the standard DHCPv4 server port.
	ServerPortV4 layers.UDPPort = 67

	// ClientPortV4 is the standard DHCPv4 client port.
	ClientPortV4 layers.UDPPort = 68
)

Port numbers for DHCPv4.

See RFC 2131 Section 4.1.

View Source
const EUI48AddrLen = 6

EUI48AddrLen is the length of a valid EUI-48 hardware address.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Interfaces stores configurations of DHCP server specific for the network
	// interface identified by its name.  It must not be empty and must only
	// contain valid interface names and configurations.
	Interfaces map[string]*InterfaceConfig

	// NetworkDeviceManager is the manager of network devices.  It must not be
	// nil.
	//
	// TODO(e.burkov):  Set.
	NetworkDeviceManager NetworkDeviceManager

	// Logger will be used to log the DHCP events.  It must not be nil.
	Logger *slog.Logger

	// LocalDomainName is the top-level domain name to use for resolving DHCP
	// clients' hostnames.  It must be a valid domain name.
	LocalDomainName string

	// DBFilePath is the path to the database file containing the DHCP leases.
	// It must not be empty.
	DBFilePath string

	// ICMPTimeout is the timeout for checking another DHCP server's presence.
	// It must be non-negative.  If it is zero, the check will be skipped.
	ICMPTimeout time.Duration

	// Enabled is the state of the service, whether it is enabled or not.
	Enabled bool
}

Config is the configuration for the DHCP service.

func (*Config) Validate added in v0.107.42

func (conf *Config) Validate() (err error)

Validate implements the validate.Interface for *Config.

type DHCPServer added in v0.107.42

type DHCPServer struct {
	// contains filtered or unexported fields
}

DHCPServer is a DHCP server for both IPv4 and IPv6 address families.

TODO(e.burkov): Rename to Default.

func New added in v0.107.42

func New(ctx context.Context, conf *Config) (srv *DHCPServer, err error)

New creates a new DHCP server with the given configuration. conf must be valid.

TODO(e.burkov): Use.

func (*DHCPServer) AddLease added in v0.107.46

func (srv *DHCPServer) AddLease(ctx context.Context, l *Lease) (err error)

AddLease implements the Interface interface for *DHCPServer.

func (*DHCPServer) Enabled added in v0.107.42

func (srv *DHCPServer) Enabled() (ok bool)

Enabled implements the Interface interface for *DHCPServer.

func (*DHCPServer) HostByIP added in v0.107.46

func (srv *DHCPServer) HostByIP(ip netip.Addr) (host string)

HostByIP implements the Interface interface for *DHCPServer.

func (*DHCPServer) IPByHost added in v0.107.46

func (srv *DHCPServer) IPByHost(host string) (ip netip.Addr)

IPByHost implements the Interface interface for *DHCPServer.

func (*DHCPServer) Leases added in v0.107.42

func (srv *DHCPServer) Leases() (leases []*Lease)

Leases implements the Interface interface for *DHCPServer.

func (*DHCPServer) MACByIP added in v0.107.46

func (srv *DHCPServer) MACByIP(ip netip.Addr) (mac net.HardwareAddr)

MACByIP implements the Interface interface for *DHCPServer.

func (*DHCPServer) RemoveLease added in v0.107.46

func (srv *DHCPServer) RemoveLease(ctx context.Context, l *Lease) (err error)

RemoveLease implements the Interface interface for *DHCPServer.

func (*DHCPServer) Reset added in v0.107.46

func (srv *DHCPServer) Reset(ctx context.Context) (err error)

Reset implements the Interface interface for *DHCPServer.

func (*DHCPServer) Shutdown added in v0.107.63

func (srv *DHCPServer) Shutdown(ctx context.Context) (err error)

Shutdown implements the Interface interface for *DHCPServer.

func (*DHCPServer) Start added in v0.107.63

func (srv *DHCPServer) Start(ctx context.Context) (err error)

Start implements the Interface interface for *DHCPServer.

func (*DHCPServer) UpdateStaticLease added in v0.107.46

func (srv *DHCPServer) UpdateStaticLease(ctx context.Context, l *Lease) (err error)

UpdateStaticLease implements the Interface interface for *DHCPServer.

TODO(e.burkov): Support moving leases between interfaces.

type Empty

type Empty struct{}

Empty is an Interface implementation that does nothing.

func (Empty) AddLease

func (Empty) AddLease(_ context.Context, _ *Lease) (err error)

AddLease implements the Interface interface for Empty.

func (Empty) Config

func (Empty) Config() (conf *Config)

Config implements the [ServiceWithConfig] interface for Empty.

func (Empty) Enabled

func (Empty) Enabled() (ok bool)

Enabled implements the Interface interface for Empty.

func (Empty) HostByIP

func (Empty) HostByIP(_ netip.Addr) (host string)

HostByIP implements the Interface interface for Empty.

func (Empty) IPByHost

func (Empty) IPByHost(_ string) (ip netip.Addr)

IPByHost implements the Interface interface for Empty.

func (Empty) Leases

func (Empty) Leases() (leases []*Lease)

Leases implements the Interface interface for Empty.

func (Empty) MACByIP

func (Empty) MACByIP(_ netip.Addr) (mac net.HardwareAddr)

MACByIP implements the Interface interface for Empty.

func (Empty) RemoveLease

func (Empty) RemoveLease(_ context.Context, _ *Lease) (err error)

RemoveLease implements the Interface interface for Empty.

func (Empty) Reset

func (Empty) Reset(_ context.Context) (err error)

Reset implements the Interface interface for Empty.

func (Empty) Shutdown

func (Empty) Shutdown(_ context.Context) (err error)

Shutdown implements the [Service] interface for Empty.

func (Empty) Start

func (Empty) Start(_ context.Context) (err error)

Start implements the [Service] interface for Empty.

func (Empty) UpdateStaticLease added in v0.107.42

func (Empty) UpdateStaticLease(_ context.Context, _ *Lease) (err error)

UpdateStaticLease implements the Interface interface for Empty.

type EmptyNetworkDevice added in v0.107.72

type EmptyNetworkDevice struct{}

EmptyNetworkDevice is an empty implementation of NetworkDevice.

func (EmptyNetworkDevice) Addresses added in v0.107.72

func (EmptyNetworkDevice) Addresses() (ips []netip.Addr)

Addresses implements the NetworkDevice interface for EmptyNetworkDevice. It always returns nil.

func (EmptyNetworkDevice) LinkType added in v0.107.72

func (EmptyNetworkDevice) LinkType() (lt layers.LinkType)

LinkType implements the NetworkDevice interface for EmptyNetworkDevice. It always returns layers.LinkTypeNull.

func (EmptyNetworkDevice) ReadPacketData added in v0.107.72

func (EmptyNetworkDevice) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

ReadPacketData implements the gopacket.PacketDataSource interface for EmptyNetworkDevice. It always returns no data, empty capture info and a nil error.

func (EmptyNetworkDevice) WritePacketData added in v0.107.72

func (EmptyNetworkDevice) WritePacketData(_ []byte) (err error)

WritePacketData implements the NetworkDevice interface for EmptyNetworkDevice. It always returns nil.

type EmptyNetworkDeviceManager added in v0.107.72

type EmptyNetworkDeviceManager struct{}

EmptyNetworkDeviceManager is an empty implementation of NetworkDeviceManager.

func (EmptyNetworkDeviceManager) Open added in v0.107.72

Open implements the NetworkDeviceManager interface for EmptyNetworkDeviceManager. It always returns EmptyNetworkDevice.

type IPv4Config

type IPv4Config struct {
	// Clock is used to get current time.  It should not be nil.
	Clock timeutil.Clock

	// GatewayIP is the IPv4 address of the network's gateway.  It is used as
	// the default gateway for DHCP clients and also used for calculating the
	// network-specific broadcast address.  It should be a valid IPv4 address,
	// should be within the subnet, and should be outside the address range.
	GatewayIP netip.Addr

	// SubnetMask is the IPv4 subnet mask of the network.  It should be a valid
	// IPv4 CIDR (i.e. all 1s followed by all 0s).
	SubnetMask netip.Addr

	// RangeStart is the first address in the range to assign to DHCP clients.
	// It should be a valid IPv4 address, should be within the subnet, and
	// should be less or equal to RangeEnd.
	RangeStart netip.Addr

	// RangeEnd is the last address in the range to assign to DHCP clients.  It
	// should be a valid IPv4 address, should be within the subnet, and should
	// be greater or equal to RangeStart.
	RangeEnd netip.Addr

	// Options is the list of explicitly configured DHCP options to send to
	// clients.  Options with nil Data field are removed from responses.
	//
	// TODO(e.burkov):  Validate.
	Options layers.DHCPOptions

	// LeaseDuration is the TTL of a DHCP lease.  It should be positive.
	LeaseDuration time.Duration

	// Enabled is the state of the DHCPv4 service, whether it is enabled or not
	// on the specific interface.
	Enabled bool
}

IPv4Config is the interface-specific configuration for DHCPv4.

func (*IPv4Config) Validate added in v0.107.63

func (c *IPv4Config) Validate() (err error)

Validate implements the validate.Interface interface for *IPv4Config.

type IPv6Config

type IPv6Config struct {
	// RangeStart is the first address in the range to assign to DHCP clients.
	// It should be a valid IPv6 address.
	RangeStart netip.Addr

	// Options is the list of explicit DHCP options to send to clients.  The
	// options with zero length are treated as deletions of the corresponding
	// options, either implicit or explicit.
	Options layers.DHCPv6Options

	// LeaseDuration is the TTL of a DHCP lease.  It should be positive.
	LeaseDuration time.Duration

	// RASlaacOnly defines whether the DHCP clients should only use SLAAC for
	// address assignment.
	RASLAACOnly bool

	// RAAllowSlaac defines whether the DHCP clients may use SLAAC for address
	// assignment.
	RAAllowSLAAC bool

	// Enabled is the state of the DHCPv6 service, whether it is enabled or not
	// on the specific interface.
	Enabled bool
}

IPv6Config is the interface-specific configuration for DHCPv6.

func (*IPv6Config) Validate added in v0.107.63

func (c *IPv6Config) Validate() (err error)

Validate implements the validate.Interface interface for *IPv6Config.

type Interface

type Interface interface {
	agh.ServiceWithConfig[*Config]

	// Enabled returns true if DHCP provides information about clients.
	Enabled() (ok bool)

	// HostByIP returns the hostname of the DHCP client with the given IP
	// address.  The address will be netip.Addr{} if there is no such client,
	// due to an assumption that a DHCP client must always have an IP address.
	HostByIP(ip netip.Addr) (host string)

	// MACByIP returns the MAC address for the given IP address leased.  It
	// returns nil if there is no such client, due to an assumption that a DHCP
	// client must always have a MAC address.
	//
	// TODO(e.burkov):  Think of a contract for the returned value.
	MACByIP(ip netip.Addr) (mac net.HardwareAddr)

	// IPByHost returns the IP address of the DHCP client with the given
	// hostname.  The hostname will be an empty string if there is no such
	// client, due to an assumption that a DHCP client must always have a
	// hostname, either set or generated.
	IPByHost(host string) (ip netip.Addr)

	// Leases returns all the active DHCP leases.  The returned slice should be
	// a clone.  The order of leases is undefined.
	//
	// TODO(e.burkov):  Consider implementing iterating methods with appropriate
	// signatures instead of cloning the whole list.
	Leases() (ls []*Lease)

	// AddLease adds a new DHCP lease.  l must be valid.  It returns an error if
	// l already exists.
	AddLease(ctx context.Context, l *Lease) (err error)

	// UpdateStaticLease replaces an existing static DHCP lease.  l must be
	// valid.  It returns an error if the lease with the given hardware address
	// doesn't exist or if other values match another existing lease.
	UpdateStaticLease(ctx context.Context, l *Lease) (err error)

	// RemoveLease removes an existing DHCP lease.  l must be valid.  It returns
	// an error if there is no lease equal to l.
	RemoveLease(ctx context.Context, l *Lease) (err error)

	// Reset removes all the DHCP leases.
	//
	// TODO(e.burkov):  If it's really needed?
	Reset(ctx context.Context) (err error)
}

Interface is a DHCP service.

TODO(e.burkov): Separate HostByIP, MACByIP, IPByHost into a separate interface. This is also applicable to Enabled method.

TODO(e.burkov): Reconsider the requirements for the leases validity.

type InterfaceConfig

type InterfaceConfig struct {
	// IPv4 is the configuration of DHCP protocol for IPv4.
	IPv4 *IPv4Config

	// IPv6 is the configuration of DHCP protocol for IPv6.
	IPv6 *IPv6Config
}

InterfaceConfig is the configuration of a single DHCP interface.

func (*InterfaceConfig) Validate added in v0.107.63

func (ic *InterfaceConfig) Validate() (err error)

Validate implements the validate.Interface interface for *InterfaceConfig.

type Lease

type Lease struct {
	// IP is the IP address leased to the client.  It must not be empty.
	IP netip.Addr

	// Expiry is the expiration time of the lease or its blocking expiration
	// time.
	Expiry time.Time

	// Hostname of the client.  It may be empty if the lease is blocked.
	Hostname string

	// HWAddr is the physical hardware (MAC) address.  It must not be nil.
	HWAddr net.HardwareAddr

	// IsStatic defines if the lease is static.
	IsStatic bool
}

Lease is a DHCP lease.

TODO(e.burkov): Consider moving it to agh, since it also may be needed in [websvc].

TODO(e.burkov): Add validation method.

func (*Lease) Clone added in v0.107.42

func (l *Lease) Clone() (clone *Lease)

Clone returns a deep copy of l.

func (*Lease) IsBlocked added in v0.107.71

func (l *Lease) IsBlocked() (blocked bool)

IsBlocked returns true if the lease is blocked.

type NetworkDevice added in v0.107.71

type NetworkDevice interface {
	gopacket.PacketDataSource

	// Addresses returns all IP addresses assigned to the device.
	Addresses() (ips []netip.Addr)

	// LinkType returns the link type of the network interface.
	LinkType() (lt layers.LinkType)

	// WritePacketData writes a serialized packet to the network interface.
	WritePacketData(data []byte) (err error)
}

NetworkDevice provides an ability of reading and writing packets to a network interface. It used to generalize implementations for different platforms and to simplify testing.

It's based on [pcap.Handle].

type NetworkDeviceConfig added in v0.107.71

type NetworkDeviceConfig struct {
	// Name is the name of the network device.  It must be a valid interface
	// name on the system.
	Name string
}

NetworkDeviceConfig is the configuration for a network device.

func (*NetworkDeviceConfig) Validate added in v0.107.71

func (conf *NetworkDeviceConfig) Validate() (err error)

Validate implements the validate.Interface interface for *NetworkDeviceConfig.

type NetworkDeviceManager added in v0.107.71

type NetworkDeviceManager interface {
	// Open opens a network device.  conf must be valid.
	Open(ctx context.Context, conf *NetworkDeviceConfig) (dev NetworkDevice, err error)
}

NetworkDeviceManager creates and manages network devices.

TODO(e.burkov): Add device closing method.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL