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
- Variables
- func ServeATA(w ResponseSender, r *Header, rs io.ReadSeeker) (int, error)
- type ATAArg
- type ATACmdStatus
- type Arg
- type Command
- type ConfigArg
- type ConfigCommand
- type Directive
- type DirectiveCommand
- type Error
- type Header
- type Identifier
- type MACMaskArg
- type MACMaskCommand
- type MACMaskError
- type ReserveReleaseArg
- type ReserveReleaseCommand
- type ResponseSender
Constants ¶
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 ¶
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 ¶
MarshalBinary allocates a byte slice containing the data from an ATAArg.
MarshalBinary never returns an error.
func (*ATAArg) UnmarshalBinary ¶
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 ¶
type Arg interface { encoding.BinaryMarshaler encoding.BinaryUnmarshaler }
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 )
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 ¶
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 ¶
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 ¶
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 ¶
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 // 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 )
type Header ¶
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 ¶
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 ¶
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 ¶
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 ¶
ResponseSender provides an interface which allows an AoE handler to construct and send a Header in response to a Request.