You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: message.go
    path of file: ./repos/sliver/vendor/github.com/mdlayher/netlink
    
    the code of the file until where you have to start completion: package netlink

import (
	"errors"
	"fmt"
	"unsafe"

	"github.com/mdlayher/netlink/nlenc"
)

// Flags which may apply to netlink attribute types when communicating with
// certain netlink families.
const (
	Nested       uint16 = 0x8000
	NetByteOrder uint16 = 0x4000

	// attrTypeMask masks off Type bits used for the above flags.
	attrTypeMask uint16 = 0x3fff
)

// Various errors which may occur when attempting to marshal or unmarshal
// a Message to and from its binary form.
var (
	errIncorrectMessageLength = errors.New("netlink message header length incorrect")
	errShortMessage           = errors.New("not enough data to create a netlink message")
	errUnalignedMessage       = errors.New("input data is not properly aligned for netlink message")
)

// HeaderFlags specify flags which may be present in a Header.
type HeaderFlags uint16

const (
	// General netlink communication flags.

	// Request in
    
func checkMessage(m Message) error {
	// NB: All non-nil errors returned from this function *must* be of type
	// OpError in order to maintain the appropriate contract with callers of
	// this package.

	// The libnl documentation indicates that type error can
	// contain error codes:
	// https://www.infradead.org/~tgr/libnl/doc/core.html#core_errmsg.
	//
	// However, rtnetlink at least seems to also allow errors to occur at the
	// end of a multipart message with done/multi and an error number.
	var hasHeader bool
	switch {
	case m.Header.Type == Error:
		// Error code followed by nlmsghdr/ext ack attributes.
		hasHeader = true
	case m.Header.Type == Done && m.Header.Flags&Multi != 0:
		// If no data, there must be no error number so just  exit early. Some
		// of the unit tests hard-coded this but I don't actually know if this
		// case occurs in the wild.
		if len(m.Data) == 0 {
			return nil
		}

		// Done|Multi potentially followed by ext ack attributes.
	default:
		// Neither, nothing to do.
		return nil
	}

	// Errno occupies 4 bytes.
	const endErrno = 4
	if len(m.Data) < endErrno {
		return newOpError("receive", errShortErrorMessage)
	}

	c := nlenc.Int32(m.Data[:endErrno])
	if c == 0 {
		// 0 indicates no error.
		return nil
	}

	oerr := &OpError{
		Op: "receive",
		// Error code is a negative integer, convert it into an OS-specific raw
		// system call error, but do not wrap with os.NewSyscallError to signify
		// that this error was produced by a netlink message; not a system call.
		Err: newError(-1 * int(c)),
	}

	// TODO(mdlayher): investigate the Capped flag.

	if m.Header.Flags&AcknowledgeTLVs == 0 {
		// No extended acknowledgement.
		return oerr
	}

	// Flags indicate an extended acknowledgement. The type/flags combination
	// checked above determines the offset where the TLVs occur.
	var off int
	if hasHeader {
		// There is an nlmsghdr preceding the TLVs.
		if len(m.Data) < endErrno+nlmsgHeaderLen {
			return newOpError("receive", errShortErrorMessage)
		}

		// The TLVs should be at the offset indicated by the nlmsghdr.length,
		// plus the offset where the header began. But make sure the calculated
		// offset is still in-bounds.
		h := *(*Header)(unsafe.Pointer(&m.Data[endErrno : endErrno+nlmsgHeaderLen][0]))
		off = endErrno + int(h.Length)

		if len(m.Data) < off {
			return newOpError("receive", errShortErrorMessage)
		}
	} else {
		// There is no nlmsghdr preceding the TLVs, parse them directly.
		off = endErrno
	}

	ad, err := NewAttributeDecoder(m.Data[off:])
	if err != nil {
		// Malformed TLVs, just return the OpError with the info we have.
		return oerr
	}

	for ad.Next() {
		switch ad.Type() {
		case 1: // unix.NLMSGERR_ATTR_MSG
			oerr.Message = ad.String()
		case 2: // unix.NLMSGERR_ATTR_OFFS
			oerr.Offset = int(ad.Uint32())
		}
	}

	// Explicitly ignore ad.Err: malformed TLVs, just return the OpError with
	// the info we have.
	return oerr
}