func (p *Packet) UnmarshalBinary(b []byte) error {
	if len(b) < 8 {
		return io.ErrUnexpectedEOF
	}
	p.HardwareType = binary.BigEndian.Uint16(b[0:2])
	p.ProtocolType = binary.BigEndian.Uint16(b[2:4])
	p.HardwareAddrLength = b[4]
	p.IPLength = b[5]
	p.Operation = Operation(binary.BigEndian.Uint16(b[6:8]))
	n := 8
	ml := int(p.HardwareAddrLength)
	ml2 := ml * 2
	il := int(p.IPLength)
	il2 := il * 2
	addrl := n + ml2 + il2
	if len(b) < addrl {
		return io.ErrUnexpectedEOF
	}
	bb := make([]byte, addrl-n)
	copy(bb[0:ml], b[n:n+ml])
	p.SenderHardwareAddr = bb[0:ml]
	n += ml
	copy(bb[ml:ml+il], b[n:n+il])
	p.SenderIP = bb[ml : ml+il]
	n += il
	copy(bb[ml+il:ml2+il], b[n:n+ml])
	p.TargetHardwareAddr = bb[ml+il : ml2+il]
	n += ml
	copy(bb[ml2+il:ml2+il2], b[n:n+il])
	p.TargetIP = bb[ml2+il : ml2+il2]
	return nil
}
UnmarshalBinary unmarshals a raw byte slice into a Packet.
package arp
import (
	"encoding/binary"
	"errors"
	"io"
	"net"
	"github.com/mdlayher/ethernet"
)
var (
	ErrInvalidHardwareAddr = errors.New("invalid hardware address")
	ErrInvalidIP = errors.New("invalid IPv4 address")
	errInvalidARPPacket = errors.New("invalid ARP packet")
)
type Operation uint16
const (
	OperationRequest Operation = 1
	OperationReply   Operation = 2
)
type Packet struct {
	HardwareType uint16
	ProtocolType uint16
	HardwareAddrLength uint8
	IPLength uint8
	Operation Operation
	SenderHardwareAddr net.HardwareAddr
	SenderIP net.IP
	TargetHardwareAddr net.HardwareAddr
	TargetIP net.IP
}
func NewPacket(op Operation, srcHW net.HardwareAddr, srcIP net.IP, dstHW net.HardwareAddr, dstIP net.IP) (*Packet, error) {
	if len(srcHW) < 6 {
		return nil, ErrInvalidHardwareAddr
	}
	if len(dstHW) < 6 {
		return nil, ErrInvalidHardwareAddr
	}
	if len(srcHW) != len(dstHW) {
		return nil, ErrInvalidHardwareAddr
	}
	srcIP = srcIP.To4()
	if srcIP == nil {
		return nil, ErrInvalidIP
	}
	dstIP = dstIP.To4()
	if dstIP == nil {
		return nil, ErrInvalidIP
	}
	return &Packet{
		HardwareType: 1,
		ProtocolType: uint16(ethernet.EtherTypeIPv4),
		HardwareAddrLength: uint8(len(srcHW)),
		IPLength:           uint8(len(srcIP)),
		Operation:          op,
		SenderHardwareAddr: srcHW,
		SenderIP:           srcIP,
		TargetHardwareAddr: dstHW,
		TargetIP:           dstIP,
	}, nil
}
func (p *Packet) MarshalBinary() ([]byte, error) {
	b := make([]byte, 2+2+1+1+2+(p.IPLength*2)+(p.HardwareAddrLength*2))
	binary.BigEndian.PutUint16(b[0:2], p.HardwareType)
	binary.BigEndian.PutUint16(b[2:4], p.ProtocolType)
	b[4] = p.HardwareAddrLength
	b[5] = p.IPLength
	binary.BigEndian.PutUint16(b[6:8], uint16(p.Operation))
	n := 8
	hal := int(p.HardwareAddrLength)
	pl := int(p.IPLength)
	copy(b[n:n+hal], p.SenderHardwareAddr)
	n += hal
	copy(b[n:n+pl], p.SenderIP)
	n += pl
	copy(b[n:n+hal], p.TargetHardwareAddr)
	n += hal
	copy(b[n:n+pl], p.TargetIP)
	return b, nil
}