code: func (f *Frame) UnmarshalBinary(b []byte) error {
  	// Verify that both hardware addresses and a single EtherType are present
  	if len(b) < 14 {
  		return io.ErrUnexpectedEOF
  	}
  
  	// Track offset in packet for reading data
  	n := 14
  
  	// Continue looping and parsing VLAN tags until no more VLAN EtherType
  	// values are detected
  	et := EtherType(binary.BigEndian.Uint16(b[n-2 : n]))
  	switch et {
  	case EtherTypeServiceVLAN, EtherTypeVLAN:
  		// VLAN type is hinted for further parsing.  An index is returned which
  		// indicates how many bytes were consumed by VLAN tags.
  		nn, err := f.unmarshalVLANs(et, b[n:])
  		if err != nil {
  			return err
  		}
  
  		n += nn
  	default:
  		// No VLANs detected.
  		f.EtherType = et
  	}
  
  	// Allocate single byte slice to store destination and source hardware
  	// addresses, and payload
  	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]
  
  	// There used to be a minimum payload length restriction here, but as
  	// long as two hardware addresses and an EtherType are present, it
  	// doesn't really matter what is contained in the payload.  We will
  	// follow the "robustness principle".
  	copy(bb[12:], b[n:])
  	f.Payload = bb[12:]
  
  	return nil
  }
docs: // UnmarshalBinary unmarshals a byte slice into a Frame.