func (f *Frame) UnmarshalBinary(b []byte) error {
	if len(b) < 14 {
		return io.ErrUnexpectedEOF
	}
	n := 14
	et := EtherType(binary.BigEndian.Uint16(b[n-2 : n]))
	for ; et == EtherTypeVLAN; n += 4 {
		if len(b[n:]) < 4 {
			return io.ErrUnexpectedEOF
		}
		vlan := new(VLAN)
		if err := vlan.UnmarshalBinary(b[n : n+2]); err != nil {
			return err
		}
		f.VLAN = append(f.VLAN, vlan)
		et = EtherType(binary.BigEndian.Uint16(b[n+2 : n+4]))
	}
	f.EtherType = et
	bb := make([]byte, 6+6+len(b[n:]))
	copy(bb[0:6], b[0:6])
	f.Destination = bb[0:6]
	copy(bb[6:12], b[6:12])
	f.Source = bb[6:12]
	copy(bb[12:], b[n:])
	f.Payload = bb[12:]
	return nil
}
UnmarshalBinary unmarshals a byte slice into a Frame.

If the byte slice does not contain enough data to unmarshal a valid Frame,
io.ErrUnexpectedEOF is returned.

If one or more VLANs are detected and their IDs are too large (greater than
4094), ErrInvalidVLAN is returned.
package ethernet
import (
	"encoding/binary"
	"errors"
	"hash/crc32"
	"io"
	"net"
)
const (
	minPayload = 46
)
var (
	Broadcast = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
)
var (
	ErrInvalidFCS = errors.New("invalid frame check sequence")
)
type EtherType uint16
const (
	EtherTypeIPv4 EtherType = 0x0800
	EtherTypeARP  EtherType = 0x0806
	EtherTypeVLAN EtherType = 0x8100
	EtherTypeIPv6 EtherType = 0x86DD
)
type Frame struct {
	Destination net.HardwareAddr
	Source net.HardwareAddr
	VLAN []*VLAN
	EtherType EtherType
	Payload []byte
}
func (f *Frame) MarshalBinary() ([]byte, error) {
	b := make([]byte, f.length())
	_, err := f.read(b)
	return b, err
}
func (f *Frame) MarshalFCS() ([]byte, error) {
	b := make([]byte, f.length()+4)
	if _, err := f.read(b); err != nil {
		return nil, err
	}
	binary.BigEndian.PutUint32(b[len(b)-4:], crc32.ChecksumIEEE(b[0:len(b)-4]))
	return b, nil
}
func (f *Frame) read(b []byte) (int, error) {
	copy(b[0:6], f.Destination)
	copy(b[6:12], f.Source)
	n := 12
	for _, v := range f.VLAN {
		binary.BigEndian.PutUint16(b[n:n+2], uint16(EtherTypeVLAN))
		if _, err := v.read(b[n+2 : n+4]); err != nil {
			return 0, err
		}
		n += 4
	}
	binary.BigEndian.PutUint16(b[n:n+2], uint16(f.EtherType))
	copy(b[n+2:], f.Payload)
	return len(b), nil
}