dhcpd: support static ip address for mac

This commit is contained in:
nadoo 2021-06-10 20:09:21 +08:00
parent 41fee381d0
commit d92e7f6191
6 changed files with 48 additions and 11 deletions

View File

@ -363,8 +363,8 @@ Examples:
## Service
- dhcpd:
- service=dhcpd,INTERFACE,START_IP,END_IP
- e.g., service=dhcpd,eth1,192.168.50.100,192.168.50.199
- service=dhcpd,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...]
- e.g., service=dhcpd,eth1,192.168.50.100,192.168.50.199,720,fc:23:ab:9e:25:01=192.168.2.101
## Linux Service

View File

@ -241,9 +241,10 @@ dnsrecord=www.example.com/1.2.3.4
dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946
# SERVICES
# service=dhcpd,INTERFACE,START_IP,END_IP
# service=dhcpd,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...]
# e.g.:
# service=dhcpd,eth1,192.168.50.100,192.168.50.199
# service=dhcpd,eth1,192.168.1.100,192.168.1.199,720
# service=dhcpd,eth2,192.168.2.100,192.168.2.199,720,fc:23:ab:9e:25:01=192.168.2.101,fc:23:ab:9e:25:02=192.168.2.102
# INTERFACE SPECIFIC
# ------------------

4
go.mod
View File

@ -8,7 +8,7 @@ require (
github.com/dgryski/go-idea v0.0.0-20170306091226-d2fb45a411fb
github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152
github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521 // indirect
github.com/insomniacslk/dhcp v0.0.0-20210528123148-fb4eaaa00ad2
github.com/insomniacslk/dhcp v0.0.0-20210608085346-465dd6c35f6c
github.com/klauspost/cpuid/v2 v2.0.6 // indirect
github.com/klauspost/reedsolomon v1.9.12 // indirect
github.com/mdlayher/raw v0.0.0-20210412142147-51b895745faf // indirect
@ -19,7 +19,7 @@ require (
github.com/xtaci/kcp-go/v5 v5.6.1
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
golang.org/x/sys v0.0.0-20210603125802-9665404d3644 // indirect
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
)
// Replace dependency modules with local developing copy

4
go.sum
View File

@ -41,6 +41,8 @@ github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
github.com/insomniacslk/dhcp v0.0.0-20210528123148-fb4eaaa00ad2 h1:WDOgJoE6rb7G6A7i1/Yyh5FJeydXeUrXHMRYJo7iFak=
github.com/insomniacslk/dhcp v0.0.0-20210528123148-fb4eaaa00ad2/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
github.com/insomniacslk/dhcp v0.0.0-20210608085346-465dd6c35f6c h1:L3EHIOG1DrTVG4aBnY+Vu0s2t/KkgrV0AYkO7BSwu3M=
github.com/insomniacslk/dhcp v0.0.0-20210608085346-465dd6c35f6c/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
@ -159,6 +161,8 @@ golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b h1:qh4f65QIVFjq9eBURLEYWqaEX
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 h1:C+AwYEtBp/VQwoLntUmQ/yx3MS9vmZaKNdw5eOpoQe8=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -4,6 +4,8 @@ import (
"context"
"errors"
"net"
"strconv"
"strings"
"time"
"github.com/insomniacslk/dhcp/dhcpv4"
@ -24,29 +26,46 @@ type dpcpd struct{}
// Run runs the service.
func (*dpcpd) Run(args ...string) {
if len(args) < 3 {
if len(args) < 4 {
log.F("[dhcpd] not enough parameters, exiting")
return
}
iface := args[0]
iface, startIP, endIP, leaseMin := args[0], args[1], args[2], args[3]
if i, err := strconv.Atoi(leaseMin); err != nil {
leaseTime = time.Duration(i) * time.Minute
}
ip, mask, err := intfaceIP4(iface)
if err != nil {
log.F("[dhcpd] get ip of interface '%s' error: %s", iface, err)
return
}
if findExistServer(iface) {
if existsServer(iface) {
log.F("[dhcpd] found existing dhcp server on interface %s, service exiting", iface)
return
}
pool, err := NewPool(leaseTime, net.ParseIP(args[1]), net.ParseIP(args[2]))
pool, err := NewPool(leaseTime, net.ParseIP(startIP), net.ParseIP(endIP))
if err != nil {
log.F("[dhcpd] error in pool init: %s", err)
return
}
// static ips
for _, host := range args[4:] {
pair := strings.Split(host, "=")
if len(pair) == 2 {
mac, err := net.ParseMAC(pair[0])
if err != nil {
break
}
ip := net.ParseIP(pair[1])
pool.LeaseStaticIP(mac, ip)
}
}
laddr := net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}
server, err := server4.NewServer(iface, &laddr, handleDHCP(ip, mask, pool))
if err != nil {
@ -118,7 +137,7 @@ func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
}
}
func findExistServer(iface string) (exists bool) {
func existsServer(iface string) (exists bool) {
client, err := nclient4.New(iface)
if err != nil {
log.F("[dhcpd] failed in dhcp client creation: %s", err)

View File

@ -87,6 +87,19 @@ func (p *Pool) LeaseIP(mac net.HardwareAddr) (net.IP, error) {
return nil, errors.New("no more ip can be leased")
}
// LeaseStaticIP leases static ip from pool according to the given mac.
func (p *Pool) LeaseStaticIP(mac net.HardwareAddr, ip net.IP) {
p.mutex.Lock()
defer p.mutex.Unlock()
for _, item := range p.items {
if item.ip.Equal(ip) {
item.mac = mac
item.expire = time.Now().Add(time.Hour * 24 * 365 * 50) // 50 years
}
}
}
// ReleaseIP releases ip from pool according to the given mac.
func (p *Pool) ReleaseIP(mac net.HardwareAddr) {
p.mutex.Lock()