From 9fa72cb7c0b59d435b5eb350ff5c097eda28f1c2 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Tue, 28 Apr 2020 17:47:58 +0300 Subject: [PATCH] + remove, list static leases --- dhcpd/dhcp_http.go | 23 ++++++++++++++- dhcpd/dhcpd.go | 45 ++++++++++++++++------------- dhcpd/v6.go | 72 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 25 deletions(-) diff --git a/dhcpd/dhcp_http.go b/dhcpd/dhcp_http.go index f2ec49c0..2a1ad40e 100644 --- a/dhcpd/dhcp_http.go +++ b/dhcpd/dhcp_http.go @@ -300,7 +300,28 @@ func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Requ return } - ip, _ := parseIPv4(lj.IP) + ip := net.ParseIP(lj.IP) + if ip != nil && ip.To16() != nil { + mac, err := net.ParseMAC(lj.HWAddr) + if err != nil { + httpError(r, w, http.StatusBadRequest, "invalid MAC") + return + } + + lease := Lease{ + IP: ip, + HWAddr: mac, + } + + err = s.v6RemoveStaticLease(lease) + if err != nil { + httpError(r, w, http.StatusBadRequest, "%s", err) + return + } + return + } + + ip, _ = parseIPv4(lj.IP) if ip == nil { httpError(r, w, http.StatusBadRequest, "invalid IP") return diff --git a/dhcpd/dhcpd.go b/dhcpd/dhcpd.go index 8ab41d36..d3204a7c 100644 --- a/dhcpd/dhcpd.go +++ b/dhcpd/dhcpd.go @@ -239,29 +239,31 @@ func (s *Server) Start() error { return wrapErrPrint(err, "Couldn't find interface by name %s", s.conf.InterfaceName) } - c, err := newFilterConn(*iface, ":67") // it has to be bound to 0.0.0.0:67, otherwise it won't see DHCP discover/request packets - if err != nil { - return wrapErrPrint(err, "Couldn't start listening socket on 0.0.0.0:67") - } - log.Info("DHCP: listening on 0.0.0.0:67") - - s.conn = c - s.cond = sync.NewCond(&s.mutex) - - s.running = true - go func() { - // operate on c instead of c.conn because c.conn can change over time - err := dhcp4.Serve(c, s) - if err != nil && !s.stopping { - log.Printf("dhcp4.Serve() returned with error: %s", err) + if false { + c, err := newFilterConn(*iface, ":67") // it has to be bound to 0.0.0.0:67, otherwise it won't see DHCP discover/request packets + if err != nil { + return wrapErrPrint(err, "Couldn't start listening socket on 0.0.0.0:67") } - _ = c.Close() // in case Serve() exits for other reason than listening socket closure - s.running = false - s.cond.Signal() - }() + log.Info("DHCP: listening on 0.0.0.0:67") + + s.conn = c + s.cond = sync.NewCond(&s.mutex) + + s.running = true + go func() { + // operate on c instead of c.conn because c.conn can change over time + err := dhcp4.Serve(c, s) + if err != nil && !s.stopping { + log.Printf("dhcp4.Serve() returned with error: %s", err) + } + _ = c.Close() // in case Serve() exits for other reason than listening socket closure + s.running = false + s.cond.Signal() + }() + } if s.conf.EnableV6 { - err := s.v6Start() + err := s.v6Start(*iface) if err != nil { return err } @@ -749,6 +751,9 @@ func (s *Server) Leases(flags int) []Lease { } s.leasesLock.RUnlock() + v6leases := s.v6GetLeases(flags) + result = append(result, v6leases...) + return result } diff --git a/dhcpd/v6.go b/dhcpd/v6.go index 8b0cdcca..9d8baf6e 100644 --- a/dhcpd/v6.go +++ b/dhcpd/v6.go @@ -13,7 +13,26 @@ import ( const valIAID = "ADGH" +func (s *Server) v6GetLeases(flags int) []Lease { + var result []Lease + s.v6LeasesLock.Lock() + for _, lease := range s.v6Leases { + if (flags&LeasesStatic) != 0 && lease.Expiry.Unix() == leaseExpireStatic { + result = append(result, *lease) + } + } + s.v6LeasesLock.Unlock() + return result +} + func (s *Server) v6AddStaticLease(l Lease) error { + if len(l.IP) != 16 { + return fmt.Errorf("invalid IP") + } + if len(l.HWAddr) != 6 { + return fmt.Errorf("invalid MAC") + } + l.Expiry = time.Unix(leaseExpireStatic, 0) s.v6LeasesLock.Lock() @@ -24,6 +43,47 @@ func (s *Server) v6AddStaticLease(l Lease) error { return nil } +// Remove a lease +func (s *Server) v6RmLease(l Lease) error { + var newLeases []*Lease + for _, lease := range s.v6Leases { + if net.IP.Equal(lease.IP, l.IP) { + if !bytes.Equal(lease.HWAddr, l.HWAddr) { + return fmt.Errorf("Lease not found") + } + continue + } + newLeases = append(newLeases, lease) + } + + if len(newLeases) == len(s.v6Leases) { + return fmt.Errorf("Lease not found") + } + + s.v6Leases = newLeases + return nil +} + +func (s *Server) v6RemoveStaticLease(l Lease) error { + if len(l.IP) != 16 { + return fmt.Errorf("invalid IP") + } + if len(l.HWAddr) != 6 { + return fmt.Errorf("invalid MAC") + } + + s.v6LeasesLock.Lock() + err := s.v6RmLease(l) + if err != nil { + s.v6LeasesLock.Unlock() + return err + } + s.dbStore() + s.v6LeasesLock.Unlock() + // s.notify(LeaseChangedRemovedStatic) + return nil +} + func (s *Server) v6FindLease(mac net.HardwareAddr) *Lease { s.v6LeasesLock.Lock() defer s.v6LeasesLock.Unlock() @@ -104,15 +164,19 @@ func (s *Server) v6PacketHandler(conn net.PacketConn, peer net.Addr, req dhcpv6. } } -func (s *Server) v6Start() error { +func (s *Server) v6Start(iface net.Interface) error { laddr := &net.UDPAddr{ - IP: net.ParseIP("::1"), + IP: net.ParseIP("::"), Port: dhcpv6.DefaultServerPort, } server, err := server6.NewServer("", laddr, s.v6PacketHandler, server6.WithDebugLogger()) if err != nil { - log.Fatal(err) + return err } - return server.Serve() + go func() { + err = server.Serve() + log.Error("DHCPv6: %s", err) + }() + return nil }