func (p *packetConn) WriteTo(b []byte, addr net.Addr, ifindex int) (int, error) {
	cm := &ipv4.ControlMessage{
		IfIndex: ifindex,
	}
	return p.ipv4pc.WriteTo(b, cm, addr)
}
WriteTo writes a packet with payload b to addr. It explicitly sends the
packet over the network interface  with the specified index.
package dhcpv4
import (
	"net"
	"golang.org/x/net/ipv4"
)
type PacketReader interface {
	ReadFrom(b []byte) (n int, addr net.Addr, ifindex int, err error)
}
type PacketWriter interface {
	WriteTo(b []byte, addr net.Addr, ifindex int) (n int, err error)
}
type PacketConn interface {
	PacketReader
	PacketWriter
	Close() error
	LocalAddr() net.Addr
}
type replyWriter struct {
	pw PacketWriter
	addr    net.UDPAddr
	ifindex int
}
func (rw *replyWriter) WriteReply(r Reply) error {
	var err error
	err = r.Validate()
	if err != nil {
		return err
	}
	bytes, err := r.ToBytes()
	if err != nil {
		return err
	}
	req := r.Request()
	addr := rw.addr
	bcast := req.GetFlags()[0] & 128
	if addr.IP.Equal(net.IPv4zero) || bcast > 0 {
		addr.IP = net.IPv4bcast
	}
	_, err = rw.pw.WriteTo(bytes, &addr, rw.ifindex)
	if err != nil {
		return err
	}
	return nil
}
type Handler interface {
	ServeDHCP(req Request)
}
func Serve(pc PacketConn, h Handler) error {
	buf := make([]byte, 65536)
	for {
		n, addr, ifindex, err := pc.ReadFrom(buf)
		if err != nil {
			return err
		}
		p, err := PacketFromBytes(buf[:n])
		if err != nil {
			continue
		}
		p.ifindex = ifindex
		if OpCode(p.Op()[0]) != BootRequest {
			continue
		}
		rw := replyWriter{
			pw: pc,
			addr:    *addr.(*net.UDPAddr),
			ifindex: ifindex,
		}
		var req Request
		switch p.GetMessageType() {
		case MessageTypeDHCPDiscover:
			req = DHCPDiscover{p, &rw}
		case MessageTypeDHCPRequest:
			req = DHCPRequest{p, &rw}
		case MessageTypeDHCPDecline:
			req = DHCPDecline{p}
		case MessageTypeDHCPRelease:
			req = DHCPRelease{p}
		case MessageTypeDHCPInform:
			req = DHCPInform{p, &rw}
		}
		if req != nil {
			h.ServeDHCP(req)
		}
	}
}
type packetConn struct {
	net.PacketConn
	ipv4pc *ipv4.PacketConn
}
func NewPacketConn(pc net.PacketConn) (PacketConn, error) {
	ipv4pc := ipv4.NewPacketConn(pc)
	if err := ipv4pc.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		return nil, err
	}
	p := packetConn{
		PacketConn: pc,
		ipv4pc:     ipv4pc,
	}
	return &p, nil
}
func (p *packetConn) ReadFrom(b []byte) (int, net.Addr, int, error) {
	n, cm, src, err := p.ipv4pc.ReadFrom(b)
	if err != nil {
		return n, src, -1, err
	}
	return n, src, cm.IfIndex, err
}