dhcpd

package
v0.0.0-...-9998b90 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2024 License: GPL-3.0 Imports: 41 Imported by: 0

README

Testing DHCP Server

Contents:

Test setup with Virtual Box

Prerequisites

To set up a test environment for DHCP server you will need:

  • Linux AG Home host machine (Virtual).
  • Virtual Box.
  • Virtual machine (guest OS doesn't matter).
Configure Virtual Box
  1. Install Virtual Box and run the following command to create a Host-Only network:

    $ VBoxManage hostonlyif create
    

    You can check its status by ip a command.

    You can also set up Host-Only network using Virtual Box menu:

    File -> Host Network Manager...
    
  2. Create your virtual machine and set up its network:

    VM Settings -> Network -> Host-only Adapter
    
  3. Start your VM, install an OS. Configure your network interface to use DHCP and the OS should ask for a IP address from our DHCP server.

  4. To see the current IP addresses on client OS you can use ip a command on Linux or ipconfig on Windows.

  5. To force the client OS to request an IP from DHCP server again, you can use dhclient on Linux or ipconfig /release on Windows.

Configure server
  1. Edit server configuration file AdGuardHome.yaml, for example:

    dhcp:
         enabled: true
         interface_name: vboxnet0
         local_domain_name: lan
         dhcpv4:
           gateway_ip: 192.168.56.1
           subnet_mask: 255.255.255.0
           range_start: 192.168.56.2
           range_end: 192.168.56.2
           lease_duration: 86400
           icmp_timeout_msec: 1000
           options: []
         dhcpv6:
           range_start: 2001::1
           lease_duration: 86400
           ra_slaac_only: false
           ra_allow_slaac: false
    
  2. Start the server

    ./AdGuardHome -v
    

    There should be a message in log which shows that DHCP server is ready:

    [info] DHCP: listening on 0.0.0.0:67
    

Quick test with DHCPTest utility

Prerequisites
Quick test

The DHCP server could be tested for DISCOVER-OFFER packets with in interactive mode.

Documentation

Overview

Package dhcpd provides a DHCP server.

Index

Constants

View Source
const (
	// DefaultDHCPLeaseTTL is the default time-to-live for leases.
	DefaultDHCPLeaseTTL = uint32(timeutil.Day / time.Second)

	// DefaultDHCPTimeoutICMP is the default timeout for waiting ICMP responses.
	DefaultDHCPTimeoutICMP = 1000
)
View Source
const (
	LeaseChangedAdded = iota
	LeaseChangedAddedStatic
	LeaseChangedRemovedStatic
	LeaseChangedRemovedAll

	LeaseChangedDBStore
)

flags for onLeaseChanged()

View Source
const (
	// ErrDupHostname is returned by addLease, validateStaticLease when the
	// modified lease has a not empty non-unique hostname.
	ErrDupHostname = errors.Error("hostname is not unique")

	// ErrDupIP is returned by addLease, validateStaticLease when the modified
	// lease has a non-unique IP address.
	ErrDupIP = errors.Error("ip address is not unique")
)
View Source
const ErrUnconfigured errors.Error = "server is unconfigured"

ErrUnconfigured is returned from the server's method when it requires the server to be configured and it's not.

Variables

This section is empty.

Functions

func OptionFQDN

func OptionFQDN(fqdn string) (opt dhcpv4.Option)

OptionFQDN returns a DHCPv4 option for sending the FQDN to the client requested another hostname.

See https://datatracker.ietf.org/doc/html/rfc4702.

Types

type DHCPServer

type DHCPServer interface {
	// ResetLeases resets leases.
	ResetLeases(leases []*dhcpsvc.Lease) (err error)
	// GetLeases returns deep clones of the current leases.
	GetLeases(flags GetLeasesFlags) (leases []*dhcpsvc.Lease)
	// AddStaticLease - add a static lease
	AddStaticLease(l *dhcpsvc.Lease) (err error)
	// RemoveStaticLease - remove a static lease
	RemoveStaticLease(l *dhcpsvc.Lease) (err error)

	// UpdateStaticLease updates IP, hostname of the lease.
	UpdateStaticLease(l *dhcpsvc.Lease) (err error)

	// FindMACbyIP returns a MAC address by the IP address of its lease, if
	// there is one.
	FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr)

	// HostByIP returns a hostname by the IP address of its lease, if there is
	// one.
	HostByIP(ip netip.Addr) (host string)

	// IPByHost returns an IP address by the hostname of its lease, if there is
	// one.
	IPByHost(host string) (ip netip.Addr)

	// WriteDiskConfig4 - copy disk configuration
	WriteDiskConfig4(c *V4ServerConf)
	// WriteDiskConfig6 - copy disk configuration
	WriteDiskConfig6(c *V6ServerConf)

	// Start - start server
	Start() (err error)
	// Stop - stop server
	Stop() (err error)
	// contains filtered or unexported methods
}

DHCPServer - DHCP server interface

type GetLeasesFlags

type GetLeasesFlags uint8

GetLeasesFlags are the flags for GetLeases.

const (
	LeasesDynamic GetLeasesFlags = 0b01
	LeasesStatic  GetLeasesFlags = 0b10

	LeasesAll = LeasesDynamic | LeasesStatic
)

GetLeasesFlags values

type Interface

type Interface interface {
	Start() (err error)
	Stop() (err error)

	// Enabled returns true if the DHCP server is running.
	//
	// TODO(e.burkov):  Currently, we need this method to determine whether the
	// local domain suffix should be considered while resolving A/AAAA requests.
	// This is because other parts of the code aren't aware of the DNS suffixes
	// in DHCP clients names and caller is responsible for trimming it.  This
	// behavior should be changed in the future.
	Enabled() (ok bool)

	// Leases returns all the leases in the database.
	Leases() (leases []*dhcpsvc.Lease)

	// MacByIP returns the MAC address of a client with ip.  It returns nil if
	// there is no such client, due to an assumption that a DHCP client must
	// always have a HardwareAddr.
	MACByIP(ip netip.Addr) (mac net.HardwareAddr)

	// 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)

	// IPByHost returns the IP address of the DHCP client with the given
	// hostname.  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.
	IPByHost(host string) (ip netip.Addr)

	WriteDiskConfig(c *ServerConfig)
}

Interface is the DHCP server that deals with both IP address families.

type OnLeaseChangedT

type OnLeaseChangedT func(flags int)

OnLeaseChangedT is a callback for lease changes.

type Server

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

Server is the DHCP service that handles DHCPv4, DHCPv6, and HTTP API.

func Create

func Create(conf *ServerConfig) (s *Server, err error)

Create initializes and returns the DHCP server handling both address families. It also registers the corresponding HTTP API endpoints.

func (*Server) AddStaticLease

func (s *Server) AddStaticLease(l *dhcpsvc.Lease) error

AddStaticLease - add static v4 lease

func (*Server) Enabled

func (s *Server) Enabled() (ok bool)

Enabled returns true when the server is enabled.

func (*Server) HostByIP

func (s *Server) HostByIP(ip netip.Addr) (host string)

HostByIP implements the Interface interface for *server.

TODO(e.burkov): Implement this method for DHCPv6.

func (*Server) IPByHost

func (s *Server) IPByHost(host string) (ip netip.Addr)

IPByHost implements the Interface interface for *server.

TODO(e.burkov): Implement this method for DHCPv6.

func (*Server) Leases

func (s *Server) Leases() (leases []*dhcpsvc.Lease)

Leases returns the list of active DHCP leases.

func (*Server) MACByIP

func (s *Server) MACByIP(ip netip.Addr) (mac net.HardwareAddr)

MACByIP returns a MAC address by the IP address of its lease, if there is one.

func (*Server) Start

func (s *Server) Start() (err error)

Start will listen on port 67 and serve DHCP requests.

func (*Server) Stop

func (s *Server) Stop() (err error)

Stop closes the listening UDP socket

func (*Server) WriteDiskConfig

func (s *Server) WriteDiskConfig(c *ServerConfig)

WriteDiskConfig - write configuration

type ServerConfig

type ServerConfig struct {
	// Called when the configuration is changed by HTTP request
	ConfigModified func() `yaml:"-"`

	// Register an HTTP handler
	HTTPRegister aghhttp.RegisterFunc `yaml:"-"`

	Enabled       bool   `yaml:"enabled"`
	InterfaceName string `yaml:"interface_name"`

	// LocalDomainName is the domain name used for DHCP hosts.  For example, a
	// DHCP client with the hostname "myhost" can be addressed as "myhost.lan"
	// when LocalDomainName is "lan".
	//
	// TODO(e.burkov):  Probably, remove this field.  See the TODO on
	// [Interface.Enabled].
	LocalDomainName string `yaml:"local_domain_name"`

	Conf4 V4ServerConf `yaml:"dhcpv4"`
	Conf6 V6ServerConf `yaml:"dhcpv6"`

	// WorkDir is used to store DHCP leases.
	//
	// Deprecated:  Remove it when migration of DHCP leases will not be needed.
	WorkDir string `yaml:"-"`

	// DataDir is used to store DHCP leases.
	DataDir string `yaml:"-"`
	// contains filtered or unexported fields
}

ServerConfig is the configuration for the DHCP server. The order of YAML fields is important, since the YAML configuration file follows it.

type V4ServerConf

type V4ServerConf struct {
	Enabled       bool   `yaml:"-" json:"-"`
	InterfaceName string `yaml:"-" json:"-"`

	GatewayIP  netip.Addr `yaml:"gateway_ip" json:"gateway_ip"`
	SubnetMask netip.Addr `yaml:"subnet_mask" json:"subnet_mask"`

	// The first & the last IP address for dynamic leases
	// Bytes [0..2] of the last allowed IP address must match the first IP
	RangeStart netip.Addr `yaml:"range_start" json:"range_start"`
	RangeEnd   netip.Addr `yaml:"range_end" json:"range_end"`

	LeaseDuration uint32 `yaml:"lease_duration" json:"lease_duration"` // in seconds

	// IP conflict detector: time (ms) to wait for ICMP reply
	// 0: disable
	ICMPTimeout uint32 `yaml:"icmp_timeout_msec" json:"-"`

	// Custom Options.
	//
	// Option with arbitrary hexadecimal data:
	//     DEC_CODE hex HEX_DATA
	// where DEC_CODE is a decimal DHCPv4 option code in range [1..255]
	//
	// Option with IP data (only 1 IP is supported):
	//     DEC_CODE ip IP_ADDR
	Options []string `yaml:"options" json:"-"`
	// contains filtered or unexported fields
}

V4ServerConf - server configuration

func (*V4ServerConf) Validate

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

Validate returns an error if c is not a valid configuration.

TODO(e.burkov): Don't set the config fields when the server itself will stop containing the config.

type V6ServerConf

type V6ServerConf struct {
	Enabled       bool   `yaml:"-" json:"-"`
	InterfaceName string `yaml:"-" json:"-"`

	// The first IP address for dynamic leases
	// The last allowed IP address ends with 0xff byte
	RangeStart net.IP `yaml:"range_start" json:"range_start"`

	LeaseDuration uint32 `yaml:"lease_duration" json:"lease_duration"` // in seconds

	RASLAACOnly  bool `yaml:"ra_slaac_only" json:"-"`  // send ICMPv6.RA packets without MO flags
	RAAllowSLAAC bool `yaml:"ra_allow_slaac" json:"-"` // send ICMPv6.RA packets with MO flags
	// contains filtered or unexported fields
}

V6ServerConf - server configuration

Jump to

Keyboard shortcuts

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