func (c *Handler) IPChanged(mac net.HardwareAddr, clientIP net.IP) {
	c.RLock()
	if client := c.table.findByMAC(mac); client != nil && client.Online && client.IP().Equal(clientIP) {
		c.RUnlock()
		return
	}
	c.RUnlock()
	if Debug {
		log.Printf("ARP ip%s validating for mac=%s", clientIP, mac)
	}
	if err := c.Request(c.config.HostMAC, c.config.HostIP, EthernetBroadcast, clientIP); err != nil {
		log.Printf("ARP request failed mac=%s: %s", mac, err)
	}
	go func() {
		for i := 0; i < 5; i++ {
			time.Sleep(time.Second * 1)
			c.RLock()
			if entry := c.table.findByMAC(mac); entry != nil && entry.IP().Equal(clientIP) {
				c.RUnlock()
				if Debug {
					log.Printf("ARP ip=%s found for mac=%s ips=%s", entry.IP(), entry.MAC, entry.IPs())
				}
				return
			}
			c.RUnlock()
			if err := c.request(c.config.HostMAC, c.config.HostIP, EthernetBroadcast, clientIP); err != nil {
				log.Printf("ARP request 2 failed mac=%s ip=%s: %s", mac, clientIP, err)
			}
		}
		log.Printf("ARP ip=%s not detect for mac=%s", clientIP, mac)
		c.RLock()
		c.table.printTable()
		c.RUnlock()
	}()
}
IPChanged is used to notify that the IP has changed.

The package will detect IP changes automatically however some clients do not
send ARP Collision Detection packets and hence do not appear as an immediate change.
This method is used to accelerate the change for example when a
new DHCP MACEntry has been allocated.
package arp
import (
	"context"
	"fmt"
	"net"
	"time"
	"log"
)
func (c *Handler) ForceIPChange(mac net.HardwareAddr, claimIP bool) error {
	if Debug {
		log.Printf("ARP force IP change mac=%s", mac)
	}
	c.Lock()
	client := c.table.findByMAC(mac)
	if client == nil || !client.Online || client.State == StateVirtualHost {
		err := fmt.Errorf("mac %s is not online", mac)
		c.Unlock()
		return err
	}
	if client.State == StateHunt {
		err := fmt.Errorf("mac %s already in hunt state", mac)
		c.Unlock()
		return err
	}
	client.State = StateHunt
	client.ClaimIP = claimIP
	ips := client.IPs()
	c.Unlock()
	for _, v := range ips {
		go c.spoofLoop(c.ctx, client, v)
	}
	return nil
}
func (c *Handler) StopIPChange(mac net.HardwareAddr) error {
	if Debug {
		log.Printf("ARP stop IP change mac=%s", mac)
	}
	c.Lock()
	defer c.Unlock()
	client := c.table.findByMAC(mac)
	if client == nil {
		err := fmt.Errorf("mac %s not found", mac)
		return err
	}
	if client.State != StateHunt {
		err := fmt.Errorf("not in hunt state mac=%s state=%s", mac, client.State)
		if Debug {
			log.Printf("ARP %s", err)
		}
		return err
	}
	client.State = StateNormal
	client.ClaimIP = false
	return nil
}
func (c *Handler) ClaimIP(ip net.IP) {
	c.Lock()
	if virtual := c.table.findVirtualIP(ip); virtual == nil {
		virtual, _ = c.table.upsert(StateVirtualHost, newVirtualHardwareAddr(), ip)
		virtual.Online = false  
	}
	c.Unlock()
}