+ dhcp custom options
Squashed commit of the following:
commit 140ac16568383cab2270e5d5ba895959902dd943
Merge: d5ed73b5 cb6ca3b0
Author: Simon Zolin <s.zolin@adguard.com>
Date: Tue Aug 25 13:46:34 2020 +0300
Merge remote-tracking branch 'origin/master' into 1585-dhcp-options
commit d5ed73b5e4f068b823fe97ab1161753670d10387
Author: Simon Zolin <s.zolin@adguard.com>
Date: Fri Aug 21 18:16:41 2020 +0300
minor
commit f5208a0b050c2dd462b32edee0379758cc6e5003
Author: Simon Zolin <s.zolin@adguard.com>
Date: Mon Jun 1 14:09:39 2020 +0300
+ dhcpv4 custom options
This commit is contained in:
parent
cb6ca3b0c4
commit
9c999f98fb
|
@ -25,12 +25,13 @@ Contents:
|
|||
* API: Find clients by IP
|
||||
* DHCP server
|
||||
* DHCP server in DNS
|
||||
* "Show DHCP interfaces" command
|
||||
* "Show DHCP status" command
|
||||
* "Check DHCP" command
|
||||
* "Enable DHCP" command
|
||||
* DHCP Custom Options
|
||||
* API: Show DHCP interfaces
|
||||
* API: Show DHCP status
|
||||
* API: Check DHCP
|
||||
* API: Enable DHCP
|
||||
* Static IP check/set
|
||||
* Add a static lease
|
||||
* API: Add a static lease
|
||||
* API: Reset DHCP configuration
|
||||
* DNS general settings
|
||||
* API: Get DNS general settings
|
||||
|
@ -429,7 +430,20 @@ DHCP leases are used in several ways by DNS module.
|
|||
> PTR 100.1.168.192.in-addr.arpa. = bills-notebook.
|
||||
|
||||
|
||||
### "Show DHCP interfaces" command
|
||||
### DHCP 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
|
||||
|
||||
|
||||
### API: Show DHCP interfaces
|
||||
|
||||
Request:
|
||||
|
||||
|
@ -452,7 +466,7 @@ Response:
|
|||
}
|
||||
|
||||
|
||||
### "Show DHCP status" command
|
||||
### API: Show DHCP status
|
||||
|
||||
Request:
|
||||
|
||||
|
@ -487,7 +501,7 @@ Response:
|
|||
}
|
||||
|
||||
|
||||
### "Check DHCP" command
|
||||
### API: Check DHCP
|
||||
|
||||
Request:
|
||||
|
||||
|
@ -535,7 +549,7 @@ If `static_ip.static` is:
|
|||
In order to use DHCP server a static IP address must be set. We failed to determine if this network interface is configured using static IP address. Please set a static IP address manually.
|
||||
|
||||
|
||||
### "Enable DHCP" command
|
||||
### API: Enable DHCP
|
||||
|
||||
Request:
|
||||
|
||||
|
@ -662,7 +676,7 @@ or:
|
|||
systemctl restart system-networkd
|
||||
|
||||
|
||||
### Add a static lease
|
||||
### API: Add a static lease
|
||||
|
||||
Request:
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package dhcpd
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/util"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
|
@ -214,3 +218,43 @@ func (s *Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
|||
func (s *Server) AddStaticLease(lease Lease) error {
|
||||
return s.srv4.AddStaticLease(lease)
|
||||
}
|
||||
|
||||
// Parse option string
|
||||
// Format:
|
||||
// CODE TYPE VALUE
|
||||
func parseOptionString(s string) (uint8, []byte) {
|
||||
s = strings.TrimSpace(s)
|
||||
scode := util.SplitNext(&s, ' ')
|
||||
t := util.SplitNext(&s, ' ')
|
||||
sval := util.SplitNext(&s, ' ')
|
||||
|
||||
code, err := strconv.Atoi(scode)
|
||||
if err != nil || code <= 0 || code > 255 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var val []byte
|
||||
|
||||
switch t {
|
||||
case "hex":
|
||||
val, err = hex.DecodeString(sval)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
case "ip":
|
||||
ip := net.ParseIP(sval)
|
||||
if ip == nil {
|
||||
return 0, nil
|
||||
}
|
||||
val = ip
|
||||
if ip.To4() != nil {
|
||||
val = ip.To4()
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return uint8(code), val
|
||||
}
|
||||
|
|
|
@ -108,3 +108,25 @@ func TestNormalizeLeases(t *testing.T) {
|
|||
assert.True(t, bytes.Equal(leases[1].HWAddr, []byte{2, 2, 3, 4}))
|
||||
assert.True(t, bytes.Equal(leases[2].HWAddr, []byte{1, 2, 3, 5}))
|
||||
}
|
||||
|
||||
func TestOptions(t *testing.T) {
|
||||
code, val := parseOptionString(" 12 hex abcdef ")
|
||||
assert.Equal(t, uint8(12), code)
|
||||
assert.True(t, bytes.Equal([]byte{0xab, 0xcd, 0xef}, val))
|
||||
|
||||
code, _ = parseOptionString(" 12 hex abcdef1 ")
|
||||
assert.Equal(t, uint8(0), code)
|
||||
|
||||
code, val = parseOptionString("123 ip 1.2.3.4")
|
||||
assert.Equal(t, uint8(123), code)
|
||||
assert.Equal(t, "1.2.3.4", net.IP(string(val)).String())
|
||||
|
||||
code, _ = parseOptionString("256 ip 1.1.1.1")
|
||||
assert.Equal(t, uint8(0), code)
|
||||
code, _ = parseOptionString("-1 ip 1.1.1.1")
|
||||
assert.Equal(t, uint8(0), code)
|
||||
code, _ = parseOptionString("12 ip 1.1.1.1x")
|
||||
assert.Equal(t, uint8(0), code)
|
||||
code, _ = parseOptionString("12 x 1.1.1.1")
|
||||
assert.Equal(t, uint8(0), code)
|
||||
}
|
||||
|
|
|
@ -50,12 +50,23 @@ type V4ServerConf struct {
|
|||
// 0: disable
|
||||
ICMPTimeout uint32 `yaml:"icmp_timeout_msec"`
|
||||
|
||||
// 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"`
|
||||
|
||||
ipStart net.IP // starting IP address for dynamic leases
|
||||
ipEnd net.IP // ending IP address for dynamic leases
|
||||
leaseTime time.Duration // the time during which a dynamic lease is considered valid
|
||||
dnsIPAddrs []net.IP // IPv4 addresses to return to DHCP clients as DNS server addresses
|
||||
routerIP net.IP // value for Option Router
|
||||
subnetMask net.IPMask // value for Option SubnetMask
|
||||
options []dhcpOption
|
||||
|
||||
// Server calls this function when leases data changes
|
||||
notify func(uint32)
|
||||
|
@ -79,3 +90,8 @@ type V6ServerConf struct {
|
|||
// Server calls this function when leases data changes
|
||||
notify func(uint32)
|
||||
}
|
||||
|
||||
type dhcpOption struct {
|
||||
code uint8
|
||||
val []byte
|
||||
}
|
||||
|
|
18
dhcpd/v4.go
18
dhcpd/v4.go
|
@ -475,6 +475,10 @@ func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
|
|||
resp.UpdateOption(dhcpv4.OptRouter(s.conf.routerIP))
|
||||
resp.UpdateOption(dhcpv4.OptSubnetMask(s.conf.subnetMask))
|
||||
resp.UpdateOption(dhcpv4.OptDNS(s.conf.dnsIPAddrs...))
|
||||
|
||||
for _, opt := range s.conf.options {
|
||||
resp.Options[opt.code] = opt.val
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -619,5 +623,19 @@ func v4Create(conf V4ServerConf) (DHCPServer, error) {
|
|||
s.conf.leaseTime = time.Second * time.Duration(conf.LeaseDuration)
|
||||
}
|
||||
|
||||
for _, o := range conf.Options {
|
||||
code, val := parseOptionString(o)
|
||||
if code == 0 {
|
||||
log.Debug("DHCPv4: bad option string: %s", o)
|
||||
continue
|
||||
}
|
||||
|
||||
opt := dhcpOption{
|
||||
code: code,
|
||||
val: val,
|
||||
}
|
||||
s.conf.options = append(s.conf.options, opt)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
|
|
@ -178,6 +178,10 @@ func TestV4DynamicLeaseGet(t *testing.T) {
|
|||
GatewayIP: "192.168.10.1",
|
||||
SubnetMask: "255.255.255.0",
|
||||
notify: notify4,
|
||||
Options: []string{
|
||||
"81 hex 303132",
|
||||
"82 ip 1.2.3.4",
|
||||
},
|
||||
}
|
||||
sIface, err := v4Create(conf)
|
||||
s := sIface.(*v4Server)
|
||||
|
@ -198,6 +202,8 @@ func TestV4DynamicLeaseGet(t *testing.T) {
|
|||
assert.Equal(t, "192.168.10.1", resp.ServerIdentifier().String())
|
||||
assert.Equal(t, "255.255.255.0", net.IP(resp.SubnetMask()).String())
|
||||
assert.Equal(t, s.conf.leaseTime.Seconds(), resp.IPAddressLeaseTime(-1).Seconds())
|
||||
assert.Equal(t, []byte("012"), resp.Options[uint8(dhcpv4.OptionFQDN)])
|
||||
assert.Equal(t, "1.2.3.4", net.IP(resp.Options[uint8(dhcpv4.OptionRelayAgentInformation)]).String())
|
||||
|
||||
// "Request"
|
||||
req, _ = dhcpv4.NewRequestFromOffer(resp)
|
||||
|
|
Loading…
Reference in New Issue