aoe

package module
v0.0.0-...-f389bba Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2016 License: MIT Imports: 8 Imported by: 8

README

aoe Build Status Coverage Status GoDoc

Package aoe implements an ATA over Ethernet server, as decribed in the AoEr11 specification. MIT Licensed.

Documentation

Overview

Package aoe implements an ATA over Ethernet server, as described in the AoEr11 specification.

The AoEr11 specification can be found here: http://www.thebrantleycoilecompany.com/AoEr11.pdf.

Index

Constants

View Source
const (
	// Version is the ATA over Ethernet protocol version used by this package.
	Version uint8 = 1

	// EtherType is the registered EtherType for ATA over Ethernet, when the
	// protocol is encapsulated in a IEEE 802.3 Ethernet frame.
	EtherType ethernet.EtherType = 0x88a2

	// BroadcastMajor and BroadcastMinor are the wildcard values for the Major
	// and Minor values in a Header.
	BroadcastMajor uint16 = 0xffff
	BroadcastMinor uint8  = 0xff
)

Variables

View Source
var (
	// ErrInvalidATARequest is returned when an invalid ATA request is rejected
	// by ServeATA.
	ErrInvalidATARequest = errors.New("invalid ATA request")

	// ErrNotImplemented is returned when functionality is not yet implemented.
	ErrNotImplemented = errors.New("not implemented")
)

Functions

func ServeATA

func ServeATA(w ResponseSender, r *Header, rs io.ReadSeeker) (int, error)

ServeATA replies to an AoE ATA request after performing the requested ATA operations on the io.ReadSeeker. ServeATA can handle a variety of ATA requests, including reads, writes, and identification.

ServeATA returns the number of bytes transmitted to a client, and any errors which occurred while processing a request.

In order to make use of the full functionality provided by ServeATA, passing a block device to it as the io.ReadSeeker is recommended. Package block can handle this functionality: https://github.com/mdlayher/block.

If r.Command is not CommandIssueATACommand, or r.Arg is not a *ATAArg, ErrInvalidATARequest is returned.

If ATA identification is requested, but rs does not implement Identifier, ErrNotImplemented is returned. This behavior will change in the future, and Identifier implementations will be optional.

If an ATA write is requested, but rs does not implement io.Writer, the ATA request will be aborted, but no error will be returned by ServeATA.

Types

type ATAArg

type ATAArg struct {
	// FlagLBA48Extended specifies if an LBA48 extended command is present in
	// this argument.  FlagATADeviceHeadRegister is not evaluated unless
	// FlagLBA48Extended is true.
	FlagLBA48Extended         bool
	FlagATADeviceHeadRegister bool

	// FlagAsynchronous specifies if a write request is to be done
	// asynchronously.
	FlagAsynchronous bool

	// FlagWrite specifies if data is to be written to a device.
	FlagWrite bool

	// TODO(mdlayher): document these fields
	ErrFeature  uint8
	SectorCount uint8
	CmdStatus   ATACmdStatus
	LBA         [6]uint8

	// Data is raw data to be transferred to and from a server.
	Data []byte
}

An ATAArg is an argument to Command 0, Issue ATA Command, (CommandIssueATACommand) as described in AoEr11, Section 3.1.

func (*ATAArg) MarshalBinary

func (a *ATAArg) MarshalBinary() ([]byte, error)

MarshalBinary allocates a byte slice containing the data from an ATAArg.

MarshalBinary never returns an error.

func (*ATAArg) UnmarshalBinary

func (a *ATAArg) UnmarshalBinary(b []byte) error

UnmarshalBinary unmarshals a byte slice into an ATAArg.

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

If bytes 10 and 11 are not zero (reserved bytes), ErrorBadArgumentParameter is returned.

type ATACmdStatus

type ATACmdStatus uint8

An ATACmdStatus is a value which indicates an ATA command or status.

const (
	// ATAErrAbort indicates than an ATA command should be aborted.
	ATAErrAbort = 0x04

	// ATACmdStatus values recognized by ServeATA.
	ATACmdStatusErrStatus   ATACmdStatus = 0x01
	ATACmdStatusReadyStatus ATACmdStatus = 0x40
	ATACmdStatusCheckPower  ATACmdStatus = 0xe5
	ATACmdStatusFlush       ATACmdStatus = 0xe7
	ATACmdStatusIdentify    ATACmdStatus = 0xec
	ATACmdStatusRead28Bit   ATACmdStatus = 0x20
	ATACmdStatusRead48Bit   ATACmdStatus = 0x24
	ATACmdStatusWrite28Bit  ATACmdStatus = 0x30
	ATACmdStatusWrite48Bit  ATACmdStatus = 0x34
)

type Arg

An Arg is an argument for a Command. Different Arg implementations are used for different types of Commands.

type Command

type Command uint8

A Command is an ATA over Ethernet command. Commands are used for operations such as issuing an ATA command, querying server configuration, reading or writing a MAC address access list, or reserving a device for client use.

const (
	// CommandIssueATACommand is used to issue an ATA command to an attached
	// ATA device.
	CommandIssueATACommand Command = 0

	// CommandQueryConfigInformation is used to set or retrieve configuration
	// information to or from a server.
	CommandQueryConfigInformation Command = 1

	// CommandMACMaskList is used to read and manage a server access control
	// list based on client MAC addresses.
	CommandMACMaskList Command = 2

	// CommandReserveRelease is used to reserve or release an ATA over
	// Ethernet target for use by a set of clients.
	CommandReserveRelease Command = 3
)

func (Command) String

func (i Command) String() string

type ConfigArg

type ConfigArg struct {
	// BufferCount specifies the maximum number of outstanding messages a
	// server can queue for processing.  Messages in excess of this value
	// are dropped.
	BufferCount uint16

	// FirmwareVersion specifies the version number of a server's firmware.
	FirmwareVersion uint16

	// SectorCount, if non-zero, specifies the maximum number of sectors a
	// server can handle in a single ATA command request.
	//
	// A value of 0 is equivalent to 2, for backward compatibility.
	SectorCount uint8

	// Version specifies the AoE protocol version a server supports.
	Version uint8

	// Command specifies the ConfigCommand carried in this argument.  Command
	// must be a 4-bit integer (0xf) or less.
	Command ConfigCommand

	// StringLength specifies the length of the String field.
	StringLength uint16

	// String specifies a server configuration string.  It can be no larger
	// than 1024 bytes.
	String []byte
}

A ConfigArg is an argument to Command 1, Query Config Information, (CommandQueryConfigInformation) as described in AoEr11, Section 3.2.

func (*ConfigArg) MarshalBinary

func (c *ConfigArg) MarshalBinary() ([]byte, error)

MarshalBinary allocates a byte slice containing the data from a ConfigArg.

If any of the following conditions occur, ErrorBadArgumentParameter is returned:

  • c.Command is larger than a 4-bit integer (0xf)
  • c.StringLength does not indicate the actual length of c.String
  • c.StringLength is greater than 1024

func (*ConfigArg) UnmarshalBinary

func (c *ConfigArg) UnmarshalBinary(b []byte) error

UnmarshalBinary unmarshals a byte slice into a ConfigArg.

If the byte slice does not contain enough data to form a valid ConfigArg, or config string length is greater than the number of remaining bytes in b, io.ErrUnexpectedEOF is returned.

If config string length is greater than 1024, ErrorBadArgumentParameter is returned.

type ConfigCommand

type ConfigCommand uint8

A ConfigCommand is a subcommand used with a ConfigArg, as described in AoEr11, Section 3.2.

const (
	// ConfigCommandRead is used to read a server's config string.
	ConfigCommandRead ConfigCommand = 0

	// ConfigCommandTest is used to request that a server respond if and only
	// if the argument string exactly matches the server's config string.
	ConfigCommandTest ConfigCommand = 1

	// ConfigCommandTestPrefix is used to request that a server respond if and
	// only if the argument string is a prefix of the server's config string.
	ConfigCommandTestPrefix ConfigCommand = 2

	// ConfigCommandSet is used to set a server's config string, if and only
	// if the server's current config string is empty.
	ConfigCommandSet ConfigCommand = 3

	// ConfigCommandForceSet is used to forcibly set a server's config string,
	// and force it to respond.
	ConfigCommandForceSet ConfigCommand = 4
)

func (ConfigCommand) String

func (i ConfigCommand) String() string

type Directive

type Directive struct {
	// Command specifies the specific command to be processed for this
	// Directive.
	Command DirectiveCommand

	// MAC specifies the hardware address of a device which should be added
	// or removed from a server's MAC mask list, depending on the value
	// of Command.
	MAC net.HardwareAddr
}

A Directive is a directive which should be processed in a MACMaskArg, as described in AoEr11, Section 3.3.

func (*Directive) MarshalBinary

func (d *Directive) MarshalBinary() ([]byte, error)

MarshalBinary allocates a byte slice containing the data from a Directive.

If d.MAC is not 6 bytes in length, ErrorBadArgumentParameter is returned.

func (*Directive) UnmarshalBinary

func (d *Directive) UnmarshalBinary(b []byte) error

UnmarshalBinary unmarshals a raw byte slice into a Directive.

If the byte slice does not contain exactly 8 bytes, io.ErrUnexpectedEOF is returned.

If byte 0 (reserved byte) is not empty, ErrorBadArgumentParameter is returned.

type DirectiveCommand

type DirectiveCommand uint8

A DirectiveCommand is a subcommand used with a Directive, as described in AoEr11, Section 3.3.

const (
	// DirectiveCommandNone indicates that no command should be processed for
	// a Directive.
	DirectiveCommandNone DirectiveCommand = 0

	// DirectiveCommandAdd indicates that the MAC address in a Directive should
	// be added to a server's MAC mask list.
	DirectiveCommandAdd DirectiveCommand = 1

	// DirectiveCommandDelete indicates that the MAC address in a Directive
	// should be deleted from a server's MAC mask list.
	DirectiveCommandDelete DirectiveCommand = 2
)

func (DirectiveCommand) String

func (i DirectiveCommand) String() string

type Error

type Error uint8

An Error is an ATA over Ethernet error code, as described in AoEr11, Section 2.4.

An error code is sent from a server to a client when an error occurs during a request.

const (
	// ErrorUnrecognizedCommandCode is returned when a server does not
	// understand the Command field in a Header.
	ErrorUnrecognizedCommandCode Error = 1

	// ErrorBadArgumentParameter is returned when an improper value exists
	// somewhere in an Arg field in a Header.
	ErrorBadArgumentParameter Error = 2

	// ErrorDeviceUnavailable is returned when a server can no longer accept
	// ATA commands.
	ErrorDeviceUnavailable Error = 3

	// ErrorConfigStringPresent is returned when a server cannot set a config
	// string, because one already exists.
	ErrorConfigStringPresent Error = 4

	// ErrorUnsupportedVersion is returned when a server does not understand
	// the Version number in a Header.
	ErrorUnsupportedVersion Error = 5

	// ErrorTargetIsReserved is returned when a command cannot be completed
	// because the target is reserved.
	ErrorTargetIsReserved Error = 6
)

func (Error) Error

func (e Error) Error() string

Error returns the string representation of an Error code.

func (Error) String

func (i Error) String() string
type Header struct {
	// Version specifies the AoE version for this Header.  Version must
	// match the Version constant in this package.
	Version uint8

	// FlagResponse indicates if a message is a response to a request.
	FlagResponse bool

	// FlagError indicates if a command generated an AoE protocol error.
	FlagError bool

	// Error contains an Error value which can be used to report problems
	// to a client.
	Error Error

	// Major and Minor specify the major and minor address of an AoE server.
	//
	// The special major value "0xffff" and minor value "0xff" are used to
	// indicate a broadcast message to all AoE servers.
	Major uint16
	Minor uint8

	// Command specifies a Command value for this message.
	Command Command

	// Tag specifies a unique tag which a client can use to correlate responses
	// with their appropriate commands.
	Tag [4]byte

	// Arg specifies an argument field, which contains different types of
	// arguments depending on the value specified in Command.
	Arg Arg
}

A Header is an ATA over Ethernet header, as described in AoEr11, Section 2.

In this package, a Header does not include the Ethernet header which encapsulates it during transport over a network. When serving ATA over Ethernet requests, Ethernet headers are transparently added and removed as needed by this package.

func (*Header) MarshalBinary

func (h *Header) MarshalBinary() ([]byte, error)

MarshalBinary allocates a byte slice containing the data from a Header.

If h.Version is not Version (1), ErrorUnsupportedVersion is returned.

If h.Arg is nil, ErrorBadArgumentParameter is returned.

func (*Header) UnmarshalBinary

func (h *Header) UnmarshalBinary(b []byte) error

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.

type Identifier

type Identifier interface {
	Identify() ([512]byte, error)
}

An Identifier is an object which can return a 512 byte array containing ATA device identification information.

type MACMaskArg

type MACMaskArg struct {
	// Command specifies the MACMaskCommand carried in this argument.
	Command MACMaskCommand

	// Error, if not empty, specifies if an error occurred while processing
	// the Directives list.
	Error MACMaskError

	// DirCount specifies the number of Directive elements in this argument.
	DirCount uint8

	// Directives specifies a list of Directive elements, which are used to
	// interact with the MAC mask list.
	Directives []*Directive
}

A MACMaskArg is an argument to Command 2, MAC Mask List, (CommandMACMaskList) as described in AoEr11, Section 3.3.

func (*MACMaskArg) MarshalBinary

func (m *MACMaskArg) MarshalBinary() ([]byte, error)

MarshalBinary allocates a byte slice containing the data from a MACMaskArg.

If m.DirCount does not indicate the actual length of m.Directives, or a Directive is malformed, ErrorBadArgumentParameter is returned.

func (*MACMaskArg) UnmarshalBinary

func (m *MACMaskArg) UnmarshalBinary(b []byte) error

UnmarshalBinary unmarshals a byte slice into a MACMaskArg.

If the byte slice does not contain enough bytes to form a valid MACMaskArg, or a Directive is malformed, io.ErrUnexpectedEOF is returned.

If byte 0 (reserved byte) is not empty, ErrorBadArgumentParameter is returned.

type MACMaskCommand

type MACMaskCommand uint8

A MACMaskCommand is a subcommand used with a MACMaskArg, as described in AoEr11, Section 3.3.

const (
	// MACMaskCommandRead reads a server's MAC mask list.
	MACMaskCommandRead MACMaskCommand = 0

	// MACMaskCommandEdit edits a server's MAC mask list.
	MACMaskCommandEdit MACMaskCommand = 1
)

func (MACMaskCommand) String

func (i MACMaskCommand) String() string

type MACMaskError

type MACMaskError uint8

A MACMaskError is an error which occurs while processing a MACMaskArg's directive list, as described in AoEr11, Section 3.3.

const (
	// MACMaskErrorUnspecified is returned when an unspecified error occurs
	// while processing a directive list.
	MACMaskErrorUnspecified MACMaskError = 1

	// MACMaskErrorBadCommand is returned when an unknown DirectiveCommand
	// is passed in a Directive.
	MACMaskErrorBadCommand MACMaskError = 2

	// MACMaskErrorListFull is returned when a server's MAC mask list is
	// completely full.
	MACMaskErrorListFull MACMaskError = 3
)

func (MACMaskError) String

func (i MACMaskError) String() string

type ReserveReleaseArg

type ReserveReleaseArg struct {
	// Command specifies the ReserveReleaseCommand carried in this argument.
	Command ReserveReleaseCommand

	// NMACs specifies the number of hardware address elements in this
	// argument.
	NMACs uint8

	// MACs specifies a list of hardware addresses, which are used to interact
	// with a server's reserve list.
	MACs []net.HardwareAddr
}

A ReserveReleaseArg is an argument to Command 3, Reserve/Release (CommandReserveRelease) as described in AoEr11, Section 3.4.

func (*ReserveReleaseArg) MarshalBinary

func (r *ReserveReleaseArg) MarshalBinary() ([]byte, error)

MarshalBinary allocates a byte slice containing the data from a ReserveReleaseArg.

If r.NMACs does not indicate the actual length of r.MACs, or one or more hardware addresses are not exactly 6 bytes in length, ErrorBadArgumentParameter is returned.

func (*ReserveReleaseArg) UnmarshalBinary

func (r *ReserveReleaseArg) UnmarshalBinary(b []byte) error

UnmarshalBinary unmarshals a byte slice into a ReserveReleaseArg.

If the byte slice does not contain enough bytes to form a valid ReserveReleaseArg, or a hardware address is malformed, io.ErrUnexpectedEOF is returned.

type ReserveReleaseCommand

type ReserveReleaseCommand uint8

A ReserveReleaseCommand is a subcommand used with a ReserveReleaseArg, as described in AoEr11, Section 3.4.

const (
	// ReserveReleaseCommandRead reads a server's reserve list.
	ReserveReleaseCommandRead ReserveReleaseCommand = 0

	// ReserveReleaseCommandSet attempts to modify a server's reserve list,
	// but only if the server's reserve list is empty or the source address of
	// the command is in the reserve list.
	ReserveReleaseCommandSet ReserveReleaseCommand = 1

	// ReserveReleaseCommandForceSet forcibly modify's a server's reserve list.
	ReserveReleaseCommandForceSet ReserveReleaseCommand = 2
)

func (ReserveReleaseCommand) String

func (i ReserveReleaseCommand) String() string

type ResponseSender

type ResponseSender interface {
	Send(*Header) (int, error)
}

ResponseSender provides an interface which allows an AoE handler to construct and send a Header in response to a Request.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL