header.go
func (h *Header) UnmarshalBinary(b []byte) error {
	// Must contain minimum length for header
	if len(b) < headerLen {
		return io.ErrUnexpectedEOF
	}

	// Version must indicate Version constant (1, at time of writing)
	h.Version = uint8(b[0] >> 4)
	if h.Version != Version {
		return ErrorUnsupportedVersion
	}

	// Flags occupy bits 5 and 6 of first byte
	h.FlagResponse = (b[0] & 0x08) != 0
	h.FlagError = (b[0] & 0x04) != 0

	// Retrieve other fields stored in network byte order
	h.Error = Error(b[1])
	h.Major = binary.BigEndian.Uint16(b[2:4])
	h.Minor = b[4]
	h.Command = Command(b[5])

	tag := [4]byte{}
	copy(tag[:], b[6:10])
	h.Tag = tag

	// Determine Arg type using Command
	var a Arg
	switch h.Command {
	case CommandIssueATACommand:
		a = new(ATAArg)
	case CommandQueryConfigInformation:
		a = new(ConfigArg)
	case CommandMACMaskList:
		a = new(MACMaskArg)
	case CommandReserveRelease:
		a = new(ReserveReleaseArg)
	default:
		// Unknown Command type
		return ErrorUnrecognizedCommandCode
	}

	// Unmarshal Arg as proper type; this may also return io.ErrUnexpectedEOF
	// or other errors
	if err := a.UnmarshalBinary(b[10:]); err != nil {
		return err
	}
	h.Arg = a

	return nil
}
func (h *Header) UnmarshalBinary(b []byte) error {
	// Must contain minimum length for header
	if len(b) < headerLen {
		return io.ErrUnexpectedEOF
	}

	// Version must indicate Version constant (1, at time of writing)
	h.Version = uint8(b[0] >> 4)
	if h.Version != Version {
		return ErrorUnsupportedVersion
	}

	// Flags occupy bits 5 and 6 of first byte
	h.FlagResponse = (b[0] & 0x08) != 0
	h.FlagError = (b[0] & 0x04) != 0

	// Retrieve other fields stored in network byte order
	h.Error = Error(b[1])
	h.Major = binary.BigEndian.Uint16(b[2:4])
	h.Minor = b[4]
	h.Command = Command(b[5])

	tag := [4]byte{}
	copy(tag[:], b[6:10])
	h.Tag = tag

	// Determine Arg type using Command
	var a Arg
	switch h.Command {
	case CommandIssueATACommand:
		a = new(ATAArg)
	case CommandQueryConfigInformation:
		a = new(ConfigArg)
	case CommandMACMaskList:
		a = new(MACMaskArg)
	case CommandReserveRelease:
		a = new(ReserveReleaseArg)
	default:
		// Unknown Command type
		return ErrorUnrecognizedCommandCode
	}

	// Unmarshal Arg as proper type; this may also return io.ErrUnexpectedEOF
	// or other errors
	if err := a.UnmarshalBinary(b[10:]); err != nil {
		return err
	}
	h.Arg = a

	return nil
}
// UnmarshalBinary unmarshals a byte slice into a Header.
//
// If the byte slice does not contain enough data to form a valid Header,
// or an argument is malformed, io.ErrUnexpectedEOF is returned.
//
// If the AoE version detected is not equal to the Version constant (1),
// ErrorUnsupportedVersion is returned.
//
// If an unknown Command type is present, ErrorUnrecognizedCommandCode is
// returned.