ipmi

package
v0.0.0-...-0e2bbfb Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2024 License: LGPL-3.0 Imports: 17 Imported by: 2

Documentation

Overview

Package ipmi implements the message and layer formats of IPMI v1.5 and v2.0. It is a subset of these specifications, with a long-term goal of implementing more commands as they become relevant.

This contains everything needed to build a particular IPMI packet, but it has no knowledge about how to string them together. That is done by the root bmc package, which heavily depends on this. This package is not internal because the root package leaks types like AuthenticationAlgorithm.

Index

Constants

This section is empty.

Variables

View Source
var (
	// CipherSuite3 represents Cipher Suite 3 (RAKP-HMAC-SHA1/HMAC-SHA1-96/AES-CBC-128),
	// which must be supported by all IPMI v2.0 BMCs as the underlying algorithms are
	// each marked as mandatory in the spec.
	CipherSuite3 = CipherSuite{
		AuthenticationAlgorithmHMACSHA1,
		IntegrityAlgorithmHMACSHA196,
		ConfidentialityAlgorithmAESCBC128,
	}

	// CipherSuite17 represents Cipher Suite 17 (RAKP-HMAC-SHA256/HMAC-SHA256-128/AES-CBC-128),
	// which is supported by newer BMCs.
	CipherSuite17 = CipherSuite{
		AuthenticationAlgorithmHMACSHA256,
		IntegrityAlgorithmHMACSHA256128,
		ConfidentialityAlgorithmAESCBC128,
	}
)
View Source
var (
	LayerTypeSessionSelector = gopacket.RegisterLayerType(
		1000,
		gopacket.LayerTypeMetadata{
			Name: "IPMI Session Selector",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &SessionSelector{}
			}),
		},
	)
	LayerTypeV1Session = gopacket.RegisterLayerType(
		1001,
		gopacket.LayerTypeMetadata{
			Name: "Session v1.5",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &V1Session{}
			}),
		},
	)
	LayerTypeGetChannelAuthenticationCapabilitiesReq = gopacket.RegisterLayerType(
		1002,
		gopacket.LayerTypeMetadata{
			Name: "Get Channel Authentication Capabilities Request",
		},
	)
	LayerTypeGetChannelAuthenticationCapabilitiesRsp = gopacket.RegisterLayerType(
		1003,
		gopacket.LayerTypeMetadata{
			Name: "Get Channel Authentication Capabilities Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetChannelAuthenticationCapabilitiesRsp{}
			}),
		},
	)
	LayerTypeV2Session = gopacket.RegisterLayerType(
		1004,
		gopacket.LayerTypeMetadata{
			Name: "Session v2.0",

			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &V2Session{}
			}),
		},
	)
	LayerTypeOpenSessionReq = gopacket.RegisterLayerType(
		1005,
		gopacket.LayerTypeMetadata{
			Name: "RMCP+ Open Session Request",
		},
	)
	LayerTypeOpenSessionRsp = gopacket.RegisterLayerType(
		1006,
		gopacket.LayerTypeMetadata{
			Name: "RMCP+ Open Session Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &OpenSessionRsp{}
			}),
		},
	)
	LayerTypeRAKPMessage1 = gopacket.RegisterLayerType(
		1007,
		gopacket.LayerTypeMetadata{
			Name: "RAKP Message 1",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &RAKPMessage1{}
			}),
		},
	)
	LayerTypeRAKPMessage2 = gopacket.RegisterLayerType(
		1008,
		gopacket.LayerTypeMetadata{
			Name: "RAKP Message 2",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &RAKPMessage2{}
			}),
		},
	)
	LayerTypeRAKPMessage3 = gopacket.RegisterLayerType(
		1009,
		gopacket.LayerTypeMetadata{
			Name: "RAKP Message 3",
		},
	)
	LayerTypeRAKPMessage4 = gopacket.RegisterLayerType(
		1010,
		gopacket.LayerTypeMetadata{
			Name: "RAKP Message 4",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &RAKPMessage4{}
			}),
		},
	)

	LayerTypeMessage = gopacket.RegisterLayerType(
		1012,
		gopacket.LayerTypeMetadata{
			Name: "IPMI Message",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &Message{}
			}),
		},
	)
	LayerTypeCloseSessionReq = gopacket.RegisterLayerType(
		1013,
		gopacket.LayerTypeMetadata{
			Name: "Close Session Request",
		},
	)
	LayerTypeGetSystemGUIDRsp = gopacket.RegisterLayerType(
		1014,
		gopacket.LayerTypeMetadata{
			Name: "Get System GUID Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetSystemGUIDRsp{}
			}),
		},
	)
	LayerTypeGetDeviceIDRsp = gopacket.RegisterLayerType(
		1015,
		gopacket.LayerTypeMetadata{
			Name: "Get Device ID Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetDeviceIDRsp{}
			}),
		},
	)
	LayerTypeGetChassisStatusRsp = gopacket.RegisterLayerType(
		1016,
		gopacket.LayerTypeMetadata{
			Name: "Get Chassis Status Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetChassisStatusRsp{}
			}),
		},
	)
	LayerTypeChassisControlReq = gopacket.RegisterLayerType(
		1017,
		gopacket.LayerTypeMetadata{
			Name: "Chassis Control Request",
		},
	)
	LayerTypeGetSDRRepositoryInfoRsp = gopacket.RegisterLayerType(
		1018,
		gopacket.LayerTypeMetadata{
			Name: "Get SDR Repository Info Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetSDRRepositoryInfoRsp{}
			}),
		},
	)
	LayerTypeGetSDRReq = gopacket.RegisterLayerType(
		1019,
		gopacket.LayerTypeMetadata{
			Name: "Get SDR Request",
		},
	)
	LayerTypeGetSDRRsp = gopacket.RegisterLayerType(
		1020,
		gopacket.LayerTypeMetadata{
			Name: "Get SDR Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetSDRRsp{}
			}),
		},
	)
	LayerTypeSDR = gopacket.RegisterLayerType(
		1021,
		gopacket.LayerTypeMetadata{
			Name: "SDR Header",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &SDR{}
			}),
		},
	)
	LayerTypeFullSensorRecord = gopacket.RegisterLayerType(
		1022,
		gopacket.LayerTypeMetadata{
			Name: "Full Sensor Record",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &FullSensorRecord{}
			}),
		},
	)
	LayerTypeGetSensorReadingReq = gopacket.RegisterLayerType(
		1023,
		gopacket.LayerTypeMetadata{
			Name: "Get Sensor Reading Request",
		},
	)
	LayerTypeGetSensorReadingRsp = gopacket.RegisterLayerType(
		1024,
		gopacket.LayerTypeMetadata{
			Name: "Get Sensor Reading Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetSensorReadingRsp{}
			}),
		},
	)
	LayerTypeGetSessionInfoReq = gopacket.RegisterLayerType(
		1025,
		gopacket.LayerTypeMetadata{
			Name: "Get Session Info Request",
		},
	)
	LayerTypeGetSessionInfoRsp = gopacket.RegisterLayerType(
		1026,
		gopacket.LayerTypeMetadata{
			Name: "Get Session Info Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetSessionInfoRsp{}
			}),
		},
	)
	LayerTypeSetSessionPrivilegeLevelReq = gopacket.RegisterLayerType(
		1027,
		gopacket.LayerTypeMetadata{
			Name: "Set Session Privilege Level Request",
		},
	)
	LayerTypeSetSessionPrivilegeLevelRsp = gopacket.RegisterLayerType(
		1028,
		gopacket.LayerTypeMetadata{
			Name: "Set Session Privilege Level Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &SetSessionPrivilegeLevelRsp{}
			}),
		},
	)
	LayerTypeGetChannelCipherSuitesReq = gopacket.RegisterLayerType(
		1029,
		gopacket.LayerTypeMetadata{
			Name: "Get Channel Cipher Suites Request",
		},
	)
	LayerTypeGetChannelCipherSuitesRsp = gopacket.RegisterLayerType(
		1030,
		gopacket.LayerTypeMetadata{
			Name: "Get Channel Cipher Suites Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &GetChannelCipherSuitesRsp{}
			}),
		},
	)
	LayerTypeReserveSDRRepositoryRsp = gopacket.RegisterLayerType(
		1031,
		gopacket.LayerTypeMetadata{
			Name: "Reserve SDR Repository Response",
			Decoder: layerexts.BuildDecoder(func() layerexts.LayerDecodingLayer {
				return &ReserveSDRRepositoryRsp{}
			}),
		},
	)
)
View Source
var (
	OperationGetChassisStatusReq = Operation{
		Function: NetworkFunctionChassisReq,
		Command:  0x01,
	}
	OperationGetChassisStatusRsp = Operation{
		Function: NetworkFunctionChassisRsp,
		Command:  0x01,
	}
	OperationChassisControlReq = Operation{
		Function: NetworkFunctionChassisReq,
		Command:  0x02,
	}
	OperationGetDeviceIDReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x01,
	}
	OperationGetDeviceIDRsp = Operation{
		Function: NetworkFunctionAppRsp,
		Command:  0x01,
	}
	OperationGetSystemGUIDReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x37,
	}
	OperationGetSystemGUIDRsp = Operation{
		Function: NetworkFunctionAppRsp,
		Command:  0x37,
	}
	OperationGetChannelAuthenticationCapabilitiesReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x38,
	}
	OperationGetChannelAuthenticationCapabilitiesRsp = Operation{
		Function: NetworkFunctionAppRsp,
		Command:  0x38,
	}
	OperationSetSessionPrivilegeLevelReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x3b,
	}
	OperationSetSessionPrivilegeLevelRsp = Operation{
		Function: NetworkFunctionAppRsp,
		Command:  0x3b,
	}
	OperationCloseSessionReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x3c,
	}
	OperationGetSDRRepositoryInfoReq = Operation{
		Function: NetworkFunctionStorageReq,
		Command:  0x20,
	}
	OperationGetSDRRepositoryInfoRsp = Operation{
		Function: NetworkFunctionStorageRsp,
		Command:  0x20,
	}
	OperationReserveSDRRepositoryReq = Operation{
		Function: NetworkFunctionStorageReq,
		Command:  0x22,
	}
	OperationReserveSDRRepositoryRsp = Operation{
		Function: NetworkFunctionStorageRsp,
		Command:  0x22,
	}
	OperationGetSDRReq = Operation{
		Function: NetworkFunctionStorageReq,
		Command:  0x23,
	}
	OperationGetSDRRsp = Operation{
		Function: NetworkFunctionStorageRsp,
		Command:  0x23,
	}
	OperationGetSensorReadingReq = Operation{
		Function: NetworkFunctionSensorReq,
		Command:  0x2d,
	}
	OperationGetSensorReadingRsp = Operation{
		Function: NetworkFunctionSensorRsp,
		Command:  0x2d,
	}
	OperationGetSessionInfoReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x3d,
	}
	OperationGetSessionInfoRsp = Operation{
		Function: NetworkFunctionAppRsp,
		Command:  0x3d,
	}
	OperationGetChannelCipherSuitesReq = Operation{
		Function: NetworkFunctionAppReq,
		Command:  0x54,
	}
	OperationGetChannelCipherSuitesRsp = Operation{
		Function: NetworkFunctionAppRsp,
		Command:  0x54,
	}
)
View Source
var (
	PayloadDescriptorIPMI = PayloadDescriptor{
		PayloadType: PayloadTypeIPMI,
	}
	PayloadDescriptorOpenSessionReq = PayloadDescriptor{
		PayloadType: PayloadTypeOpenSessionReq,
	}
	PayloadDescriptorOpenSessionRsp = PayloadDescriptor{
		PayloadType: PayloadTypeOpenSessionRsp,
	}
	PayloadDescriptorRAKPMessage1 = PayloadDescriptor{
		PayloadType: PayloadTypeRAKPMessage1,
	}
	PayloadDescriptorRAKPMessage2 = PayloadDescriptor{
		PayloadType: PayloadTypeRAKPMessage2,
	}
	PayloadDescriptorRAKPMessage3 = PayloadDescriptor{
		PayloadType: PayloadTypeRAKPMessage3,
	}
	PayloadDescriptorRAKPMessage4 = PayloadDescriptor{
		PayloadType: PayloadTypeRAKPMessage4,
	}
)
View Source
var (
	// ErrNotLinearised is returned if Lineariser() is called on a linear or
	// non-linear linearisation. Linear sensors' values do not require any
	// transformation by virtue of the sensor already being linear. If the sensor
	// is non-linear, the conversion factors returned by Get Sensor Reading
	// Factors are all that are needed to obtain a real value: by being unique
	// to the raw sensor reading, there is no need for a separate linearisation
	// formula.
	//
	// Linearise() could return a no-op lineariser, however the current
	// implementation should never ask for one on a non-linearised sensor, so
	// instead we return an error to flag up a possible bug.
	ErrNotLinearised = errors.New(
		"only linearised sensors have a linearisation formula")
)

Functions

func RegisterOEMPayloadDescriptor

func RegisterOEMPayloadDescriptor(enterprise iana.Enterprise, payloadID uint16, LayerType gopacket.LayerType)

RegisterOEMPayloadDescriptor adds or overrides how an IPMI v2.0 OEM payload is handled within a session. This is implemented via a map, so care must be taken to not call this function in parallel.

Types

type AES128CBC

type AES128CBC struct {
	layers.BaseLayer
	// contains filtered or unexported fields
}

AES128CBC implements the AES-128-CBC confidentiality algorithm specified in section 13.29 of IPMI v2.0. It is a payload layer type, used to encrypt and decrypt IPMI messages. Note the default instance is not usable: use NewAES128CBC() to create one.

func NewAES128CBC

func NewAES128CBC(k2 [16]byte) (*AES128CBC, error)

func (*AES128CBC) CanDecode

func (a *AES128CBC) CanDecode() gopacket.LayerClass

func (*AES128CBC) DecodeFromBytes

func (a *AES128CBC) DecodeFromBytes(data []byte, _ gopacket.DecodeFeedback) error

DecodeFromBytes decodes an AES-128-CBC confidentiality layer. Although a precise error is returned, care should be taken when displaying this, as it can lead to a padding oracle attack (essentially, don't reveal the difference between "decryption failed" and "invalid padding" errors).

func (*AES128CBC) LayerType

func (*AES128CBC) LayerType() gopacket.LayerType

func (*AES128CBC) NextLayerType

func (a *AES128CBC) NextLayerType() gopacket.LayerType

func (*AES128CBC) SerializeTo

type Address

type Address uint8

Address represents either a slave address or software ID. The LSB is 0 in the case of the former, and 1 in the case of the latter.

func (Address) IsSlaveAddress

func (a Address) IsSlaveAddress() bool

func (Address) IsSoftwareID

func (a Address) IsSoftwareID() bool

func (Address) String

func (a Address) String() string

type AnalogDataFormat

type AnalogDataFormat uint8

AnalogDataFormat represents the binary format of analog sensor readings and thresholds. It is specified in byte 21 of the Full Sensor Record table in 37.1 and 43.1 of v1.5 and v2.0 respectively. It is a 2-bit uint on the wire.

const (
	// AnalogDataFormatUnsigned indicates an unsigned analog sensor. It is also
	// used in the case where the sensor provides neither analog readings nor
	// thresholds.
	AnalogDataFormatUnsigned AnalogDataFormat = iota
	AnalogDataFormatOnesComplement
	AnalogDataFormatTwosComplement

	// AnalogDataFormatNotAnalog indicates the sensor does not have numeric
	// readings, only thresholds.
	AnalogDataFormatNotAnalog
)

func (AnalogDataFormat) Description

func (f AnalogDataFormat) Description() string

func (AnalogDataFormat) Parser

Parser returns an AnalogDataFormatParser instance capable of turning raw values from this sensor (including normal/sensor min/max) into native Go values. If the format does not have a parser, e.g. AnalogDataFormatNotAnalog, this returns an error.

func (AnalogDataFormat) String

func (f AnalogDataFormat) String() string

type AnalogDataFormatParser

type AnalogDataFormatParser interface {

	// Parse turns an 8-bit raw sensor value into its Go value.  This returns an
	// int16 as this is the "smallest" integral type that can return a superset
	// of these 3 binary formats.
	Parse(byte) int16
}

AnalogDataFormatParser is implemented by types that can convert a raw sensor reading into a native int16. The interface's purpose is to abstract over 8-bit values on the wire that could be unsigned, 1's complement or 2's complement.

type AnalogDataFormatParserFunc

type AnalogDataFormatParserFunc func(byte) int16

AnalogDataFormatParserFunc is a convenience type allowing functions to statelessly implement AnalogDataFormatParser.

func (AnalogDataFormatParserFunc) Parse

Parse calls the underlying function with the raw input value, returning the result.

type AuthenticationAlgorithm

type AuthenticationAlgorithm uint8

AuthenticationAlgorithm is the 6-bit identifier of an authentication algorithm used in the RMCP+ session establishment process. It has no use once the session is active. The numbers are defined in 13.28 of the spec. IPMI v1.5's equivalent is authentication type.

const (
	// AuthenticationAlgorithmNone is equivalent to
	// AuthenticationAlgorithmHMACSHA1, however the key exchange authentication
	// code fields in RAKP2 and 3, and the ICV field in RAKP4 are absent.
	// Password auth and packet level integrity checking are unavailable. The
	// privilege level is established using only the username/role (the former
	// of which may be null, with a null password, allowing anonymous access).
	// Support for this algorithm is mandatory.
	AuthenticationAlgorithmNone AuthenticationAlgorithm = iota

	// AuthenticationAlgorithmHMACSHA1 specifies that HMAC-SHA1 (RFC2104) is
	// used to create 20-byte key exchange authentication code fields in RAKP2
	// and RAKP3. HMAC-SHA1-96 (RFC2404) is used for generating a 12-byte ICV in
	// RAKP4. Support for this algorithm is mandatory.
	AuthenticationAlgorithmHMACSHA1

	// AuthenticationAlgorithmHMACMD5 specifies that HMAC-MD5 (RFC2104) is used
	// to create 16-byte key exchange authentication codes in RAKP2 and RAKP3,
	// and ICV in RAKP4.
	AuthenticationAlgorithmHMACMD5

	// AuthenticationAlgorithmHMACSHA256 specifies that HMAC-SHA256 (FIPS 180-2,
	// RFC4634) is used to create 32-byte key exchange authentication code
	// fields in RAKP2 and RAKP3. HMAC-SHA256-128 (RFC4868) is used for
	// generating a 12-byte ICV in RAKP4.
	AuthenticationAlgorithmHMACSHA256
)

func (AuthenticationAlgorithm) String

func (a AuthenticationAlgorithm) String() string

type AuthenticationPayload

type AuthenticationPayload struct {

	// Wildcard asks the BMC to choose an algorithm based on the requested max
	// privilege level. If this is true, Algorithm is null.
	Wildcard bool

	// Algorithm is the authentication algorithm to indicate support for. If
	// this is non-null, Wildcard is false.
	Algorithm AuthenticationAlgorithm
}

AuthenticationPayload indicates a single authentication algorithm preference embedded in an RMCP+ Open Session Request message. One or more of these may be specified to indicate support for multiple algorithms, however this is uncommon (there is no mechanism in OpenIPMI for multiple payloads of a given type).

func (*AuthenticationPayload) Deserialise

func (a *AuthenticationPayload) Deserialise(d []byte, df gopacket.DecodeFeedback) ([]byte, error)

Deserialise reads an authentication payload from the supplied byte slice, returning unconsumed remaining bytes representing other payloads. If the payload is invalid, a nil slice is returned, and the payload is left in an unspecified state.

func (*AuthenticationPayload) Serialise

Serialise encodes the authentication payload onto the end of a buffer, returning an error if one occurs.

type AuthenticationType

type AuthenticationType uint8

AuthenticationType is used in the IPMI session header to indicate which authentication algorithm was used to sign the message. It is a 4-bit uint on the wire.

const (
	AuthenticationTypeNone AuthenticationType = iota
	AuthenticationTypeMD2
	AuthenticationTypeMD5

	AuthenticationTypePassword
	AuthenticationTypeOEM
	AuthenticationTypeRMCPPlus // IPMI v2 only
)

func (AuthenticationType) String

func (t AuthenticationType) String() string

type BodyCode

type BodyCode uint8

BodyCode is the type of defining body codes, used to indicate the structure of request and response data when the network function is Group Extension (0x2c,0x2d). See section 5.1 in the v1.5 and v2.0 specifications. This value becomes the first byte of IPMI message data, however in this implementation it is part of the message to ease selection of the data layer type.

const (
	BodyCodePICMG BodyCode = 0x00
	BodyCodeDMTF  BodyCode = 0x01
	BodyCodeSSI   BodyCode = 0x02
	BodyCodeVSO   BodyCode = 0x03
	BodyCodeDCMI  BodyCode = 0xdc
)

func (BodyCode) String

func (b BodyCode) String() string

type Channel

type Channel uint8

Channel specifies a channel number, which corresponds to an interface on the BMC. It can be thought of as a little like a port number, where each number supports a different media connection type (IPMB, LAN, serial etc.). Channels numbers are specified in section 6.3 of both IPMI v1.5 and IPMI v2.0; on the wire, they are a 4-bit uint. Channels' protocol and mediums can be discovered with the Get Channel Info command. Sessions allow multiplexing on a (session-based) channel.

const (
	ChannelPrimaryIPMB Channel = 0x0

	// ChannelPresentInterface means the current channel this value is sent
	// over, or "this" channel.
	ChannelPresentInterface Channel = 0xe

	ChannelSystemInterface Channel = 0xf
)

func (Channel) String

func (c Channel) String() string

func (Channel) Valid

func (c Channel) Valid() bool

Valid returns whether a given channel number is valid, which is in the range 0 through 0xf. Values outside this range should be regarded as an indication of lack of support.

type ChassisControl

type ChassisControl uint

ChassisControl represents a command for the chassis, e.g. power up, or hard reset. Possible values are defined by the Chassis Control command in table 22-4 and 28-4 of IPMI v1.5 and 2.0 respectively. This is a 4-bit uint on the wire.

const (
	// ChassisControlPowerOff forces the system into a soft off (S4/S5) state.
	// Unlike ChassisControlSoftPowerOff, this does not initiate a clean
	// shutdown of the OS prior to powering down.
	ChassisControlPowerOff ChassisControl = iota

	// ChassisControlPowerOn powers up the chassis.
	ChassisControlPowerOn

	// ChassisControlPowerCycle reboots the machine. The spec recommends that
	// this be a no-op if the system is powered down (S4/S5) and returns a 0xd5
	// completion code, however this command may cause some machines to power
	// up.
	ChassisControlPowerCycle

	// ChassisControlHardReset performs a hardware reset of the chassis,
	// excluding the chassis device itself. For host systems, this corresponds
	// to a system hard reset.
	ChassisControlHardReset

	// ChassisControlDiagnosticInterrupt pulses a diagnostic interrupt to the
	// CPU(s), usually causing a diagnostic dump. The exact interrupt delivered
	// is architecture-dependent.
	ChassisControlDiagnosticInterrupt

	// ChassisControlSoftPowerOff emulates a fatal over-temperature, causing a
	// soft-shutdown of the OS via ACPI. This is not supported by all chassis.
	ChassisControlSoftPowerOff
)

func (ChassisControl) Description

func (c ChassisControl) Description() string

Description returns a human-readable representation of the command.

func (ChassisControl) String

func (c ChassisControl) String() string

type ChassisControlCmd

type ChassisControlCmd struct {
	Req ChassisControlReq
}

func (*ChassisControlCmd) Name

func (*ChassisControlCmd) Name() string

Name returns "Chassis Control".

func (*ChassisControlCmd) Operation

func (*ChassisControlCmd) Operation() *Operation

Operation returns OperationChassisControlReq.

func (*ChassisControlCmd) RemoteLUN

func (c *ChassisControlCmd) RemoteLUN() LUN

func (*ChassisControlCmd) Request

func (*ChassisControlCmd) Response

type ChassisControlReq

type ChassisControlReq struct {
	layers.BaseLayer

	// ChassisControl is the control command to send to the BMC, e.g. power up.
	ChassisControl ChassisControl
}

ChassisControlReq represents a Chassis Control command, specified in section 22.3 and 28.3 of IPMI v1.5 and 2.0 respectively.

func (*ChassisControlReq) LayerType

func (*ChassisControlReq) LayerType() gopacket.LayerType

func (*ChassisControlReq) SerializeTo

type ChassisIdentifyState

type ChassisIdentifyState uint8

ChassisIdentifyState indicates the current state of the chassis identification mechanism, usually a flashing light.

const (
	// ChassisIdentifyStateOff means the chassis identification mechanism is
	// not currently active.
	ChassisIdentifyStateOff ChassisIdentifyState = iota

	// ChassisIdentifyStateTemporary means the chassis identification mechanism
	// is active, but will disable automatically at an unknown point in the
	// future.
	ChassisIdentifyStateTemporary

	// ChassisIdentifyStateIndefinite means the chassis identification mechanism
	// will remain active until manually disabled.
	ChassisIdentifyStateIndefinite

	// ChassisIdentifyStateUnknown means the BMC indicated it does not support
	// revealing the identify state in the Get Chassis Status command, however
	// it may still be supported via other means - issue a Get Command Support
	// command to find out.
	ChassisIdentifyStateUnknown ChassisIdentifyState = 0xff
)

func (ChassisIdentifyState) Description

func (s ChassisIdentifyState) Description() string

Description returns a human-readable representation of the state.

func (ChassisIdentifyState) String

func (s ChassisIdentifyState) String() string

type CipherSuite

CipherSuite represents the authentication, integrity and confidentiality triple of algorithms used to establish a session. Each BMC supports one or more sets of these, the most common being 3 and 17. The default value is equivalent to Cipher Suite 0, which should be disabled on all BMCs. This struct must be comparable.

func (CipherSuite) String

func (c CipherSuite) String() string

type CipherSuiteID

type CipherSuiteID uint8

CipherSuiteID represents the 8-bit numeric identity of a cipher suite. There are currently 20 standard cipher suites (0-19), with the most common being 3, for which support is mandatory, and 17. Higher identities are not necessarily more secure.

func (CipherSuiteID) Description

func (c CipherSuiteID) Description() string

func (CipherSuiteID) String

func (c CipherSuiteID) String() string

type CipherSuiteRecord

type CipherSuiteRecord struct {
	CipherSuiteID
	CipherSuite

	// Enterprise is 0 if the cipher suite is standard.
	iana.Enterprise
}

CipherSuiteRecord represents an identified trio of algorithms, plus IANA enterprise number if OEM-specific. While an OEM can implement a single suite ID supporting multiple integrity and confidentiality algorithms, this has not been observed, and can be represented by multiple instances of this struct.

type CloseSessionCmd

type CloseSessionCmd struct {
	Req CloseSessionReq
}

func (*CloseSessionCmd) Name

func (*CloseSessionCmd) Name() string

Name returns "Close Session".

func (*CloseSessionCmd) Operation

func (*CloseSessionCmd) Operation() *Operation

Operation returns OperationCloseSessionReq.

func (*CloseSessionCmd) RemoteLUN

func (c *CloseSessionCmd) RemoteLUN() LUN

func (*CloseSessionCmd) Request

func (*CloseSessionCmd) Response

func (c *CloseSessionCmd) Response() gopacket.DecodingLayer

type CloseSessionReq

type CloseSessionReq struct {
	layers.BaseLayer

	// ID is the ID of the session to close. In the case of IPMI v2.0, this is
	// the manage system's session ID - not the remote console's. If this is
	// null, the session handle is additionally sent. It must be non-null when
	// using IPMI v1.5 to ensure the Handle field is not sent.
	ID uint32

	// Handle is the session handle to close, only used if the ID is null. The
	// handle can be obtained via Get Session Info if necessary. 0x00 is
	// reserved, however will be encoded and decoded. This field is only
	// specified in IPMI v2.0.
	Handle SessionHandle
}

CloseSessionReq implements the Close Session command, specified in section 18.17 of v1.5 and 22.19 of v2.0. It immediately terminates the specified session. The sending user must be operating with administrator privileges to close any session other than the one this request is sent over.

func (*CloseSessionReq) LayerType

func (*CloseSessionReq) LayerType() gopacket.LayerType

func (*CloseSessionReq) SerializeTo

type Command

type Command interface {

	// Name returns the name of the command, without request/response suffix
	// e.g. "Get Device ID". This is used for metrics.
	Name() string

	// Operation returns the operation parameters for the request. This should
	// avoid allocation, referencing a value in static memory. Technically, this
	// should be a member of a Request interface that embeds
	// gopacket.SerializableLayer, however it is here to allow Request() to
	// return nil for commands not requiring a request payload, which would
	// otherwise need to have a no-op layer created.
	Operation() *Operation

	// RemoteLUN is set in the Message layer. This is usually LUNBMC, however
	// some sensors may come under OEM LUNs, requiring a Get Sensor Reading
	// invocation to use these.
	RemoteLUN() LUN

	// Request returns the possibly-nil request layer that we send to the
	// managed system. This should not allocate any additional memory.
	Request() gopacket.SerializableLayer

	// Response returns the possibly-nil response layer that we expect back from
	// the managed system following our request. This should not allocate any
	// additional memory.
	Response() gopacket.DecodingLayer
}

Command represents the request and response parts (if any) of executing a function against a managed system. Implementations of this interface have the -Cmd suffix.

Allocating the command should allocate both its request and response layers - if we allocate a request, the chances are we will be sending it and so will need the response, so this reduces load on GC. It is recommended to implement this interface using a struct with up to two value layers.

Note that this interface only applies to activity below the message layer, i.e. with a NetFn and command number. RMCP+ session setup payloads (RAKP1/2/3/4, RMCP+ Open Session Req/Rsp), while they could be considered commands, do not fall into this category. This turns out not to be so bad, as they are not on the hot path, so it is nice to be able to treat them differently.

type CommandNumber

type CommandNumber uint8

CommandNumber represents a particular function that can be requested. CommandNumber identifiers are only unique within a given network function. See Appendix G in the v1.5 and v2.0 specs for assignments. This is a 1 byte uint on the wire. It has the "Number" suffix in order to avoid colliding with the Command interface, which is much more likely to be interacted with by users, so wins the shorter name, even if this is called Command in the spec.

func (CommandNumber) String

func (c CommandNumber) String() string

type CompletionCode

type CompletionCode uint8

CompletionCode indicates whether a command executed successfully. It is analogous to a command status code. It is a 1 byte uint on the wire. Values are specified in Table 5-2 of the IPMI v2.0 spec.

N.B. if the completion code is not 0, the rest of the response may be truncated, and if it is not, the remaining structure is OEM-dependent, so in practice the rest of the message should be uninterpreted.

const (
	CompletionCodeNormal CompletionCode = 0x0

	// CompletionCodeInvalidSessionID is returned by Close Session if the
	// specified session ID does not match one the BMC knows about. Whether
	// this is also returned if the used doesn't have the required privileges
	// is untested.
	CompletionCodeInvalidSessionID CompletionCode = 0x87

	CompletionCodeNodeBusy            CompletionCode = 0xc0
	CompletionCodeUnrecognisedCommand CompletionCode = 0xc1
	CompletionCodeTimeout             CompletionCode = 0xc3

	// CompletionCodeReservationCanceledOrInvalid means that either the
	// requester's reservation has been canceled or the request's reservation
	// ID is invalid.
	CompletionCodeReservationCanceledOrInvalid CompletionCode = 0xc5

	// CompletionCodeRequestTruncated means the request ended prematurely. Did
	// you forget to add the final request data layer?
	CompletionCodeRequestTruncated CompletionCode = 0xc6

	// CompletionCodeInsufficientPrivileges indicates the channel or effective
	// user privilege level is insufficient to execute the command, or the
	// request was blocked by the firmware firewall.
	CompletionCodeInsufficientPrivileges CompletionCode = 0xd4

	CompletionCodeUnspecified CompletionCode = 0xff
)

func (CompletionCode) Description

func (c CompletionCode) Description() string

func (CompletionCode) IsTemporary

func (c CompletionCode) IsTemporary() bool

IsTemporary returns whether the code indicates a retry may produce a successful result, or the error is permanent.

func (CompletionCode) String

func (c CompletionCode) String() string

type ConfidentialityAlgorithm

type ConfidentialityAlgorithm uint8

ConfidentialityAlgorithm is the 6-bit identifier of an encryption algorithm used in the RMCP+ session establishment process. Packets with the encryption bit set in the session header are encrypted as per the specification for this algorithm.

const (
	ConfidentialityAlgorithmNone ConfidentialityAlgorithm = iota

	// ConfidentialityAlgorithmAESCBC128 specifies the use of AES-128-CBC (the
	// naming is to be consistent with the spec) for encrypted packets. The
	// confidentiality header in the IPMI payload is a 16-byte IV, randomly
	// generated for each message. The confidentiality trailer consists of a pad
	// of length between 0 and 15 to get the data to encrypt to be a multiple of
	// the algorithm block size (16), followed by the number of these bytes
	// added. The pad bytes start at 0x01, and increment each byte;
	// implementations must validate this. Support for this algorithm is
	// mandatory.
	ConfidentialityAlgorithmAESCBC128

	ConfidentialityAlgorithmXRC4128
	ConfidentialityAlgorithmXRC440
)

func (ConfidentialityAlgorithm) String

func (c ConfidentialityAlgorithm) String() string

type ConfidentialityPayload

type ConfidentialityPayload struct {

	// Wildcard asks the BMC to choose an algorithm based on the requested max
	// privilege level. If this is true, Algorithm is null.
	Wildcard bool

	// Algorithm is the confidentiality algorithm to indicate support for. If
	// this is non-null, Wildcard is false.
	Algorithm ConfidentialityAlgorithm
}

ConfidentialityPayload indicates a single confidentiality algorithm preference embedded in an RMCP+ Open Session Request message. One or more of these may be specified to indicate support for multiple algorithms, however this is uncommon (there is no mechanism in OpenIPMI for multiple payloads of a given type).

func (*ConfidentialityPayload) Deserialise

func (c *ConfidentialityPayload) Deserialise(d []byte, df gopacket.DecodeFeedback) ([]byte, error)

Deserialise reads a confidentiality payload from the supplied byte slice, returning unconsumed remaining bytes representing other payloads. If the payload is invalid, a nil slice is returned, and the payload is left in an unspecified state.

func (*ConfidentialityPayload) Serialise

Serialise encodes the confidentiality payload onto the end of a buffer, returning an error if one occurs.

type ConversionFactors

type ConversionFactors struct {

	// M is the constant multiplier. This is a 10-bit 2's complement number on
	// the wire.
	M int16

	// B is the additive offset. This is a 10-bit 2's complement number on the
	// wire.
	B int16

	// BExp is the exponent, controlling the location of the decimal point in B.
	// This is also referred to as K1 in the spec, and is a 4-bit 2's complement
	// number on the wire.
	BExp int8

	// RExp is the result exponent, controlling the location of the decimal
	// point in the result of the linear formula and hence input to the
	// linearisation function. This is also referred to as K2 in the spec, and
	// is a 4-bit 2's complement number on the wire.
	RExp int8
}

ConversionFactors contains inputs to the linear formula in 30.3 and 36.3 of v1.5 and v2.0 respectively. This struct exists as conversion factors can come from two sources: full sensor records, and the Get Sensor Reading Factors command response. In practice, we get them from the former for linear and linearised sensors, as these have constant factors. We need to obtain them from the Get Sensor Reading Factors command for non-linear sensors, as they vary by reading here. Both FullSensorRecord and GetSensorReadingFactorsRsp embed this type.

Note that we split application of the formula into "conversion" and "linearisation". Conversion happens first, and is the linear formula applied to the raw value. The linearisation step, which is a no-op for linear and non-linear sensors, applies one of the formulae in the specification to the result of the conversion. This struct only deals with conversion; see Lineariser for linearisation.

func (*ConversionFactors) ConvertReading

func (f *ConversionFactors) ConvertReading(raw int16) float64

ConvertReading applies the linear formula to a raw sensor reading, without the linearisation formula. It is independent of unit. This method takes an int16 rather than uint8 as raw values can be in 1 or 2's complement, or unsigned, so it must accept from -128 (lowest 2's complement) to 255 (highest unsigned). The conversion from the raw format to a native int must be done before calling this method.

type EntityID

type EntityID uint8

EntityID identifies the kind of hardware that a sensor or device is associated with, e.g. it distinguishes a processor from a power supply from a fan. EntityID codes can be found in 37.14 and 43.14 of IPMI v1.5 and 2.0 respectively.

A separate "instance" field discriminates between multiple occurrences of a given entity, e.g. multi-core CPUs and redundant power supplies. All sensors pertaining to a given piece of hardware will have the same entity and instance.

const (
	EntityIDUnspecified EntityID = iota
	EntityIDOther

	EntityIDProcessor
	EntityIDDisk
	EntityIDPeripheralBay
	EntityIDSystemManagementModule
	EntityIDSystemBoard
	EntityIDMemoryModule
	EntityIDProcessorModule
	EntityIDPowerSupply
	EntityIDAddInCard
	EntityIDFrontPanelBoard
	EntityIDBackPanelBoard
	EntityIDPowerSystemBoard
	EntityIDDriveBackplane

	EntityIDSystemChassis EntityID = 0x17
	EntityIDCoolingDevice EntityID = 0x1d
	EntityIDMemoryDevice  EntityID = 0x20

	EntityIDAirInlet EntityID = 0x37

	// EntityIDDCMIAirInlet allows associating temperature sensors to the
	// airflow at an air inlet. This is effectively deprecated, used by DCMI
	// v1.0 and v1.1. EntityIDAirInlet should be preferred.
	EntityIDDCMIAirInlet EntityID = 0x40

	// EntityIDDCMIProcessor is effectively deprecated, used by DCMI v1.0 and
	// v1.1. EntityIDProcessor should be preferred.
	EntityIDDCMIProcessor EntityID = 0x41

	// EntityIDDCMISystemBoard is effectively deprecated, used by DCMI v1.0 and
	// v1.1. EntityIDSystemBoard should be preferred.
	EntityIDDCMISystemBoard EntityID = 0x42
)

func (EntityID) Description

func (e EntityID) Description() string

func (EntityID) String

func (e EntityID) String() string

type EntityInstance

type EntityInstance uint8

EntityInstance distinguishes between multiple occurrences of a particular entity type in the system, e.g. if it has two processors, their SDRs will each have different instance numbers. There are no semantics around the "first" instance ID for a given entity, and they are not guaranteed to be consecutive. Some manufacturers use the same instance to refer to multiple distinct pieces of hardware, e.g. all fans could be behind 29.1. This is a 7-bit uint on the wire. See sections 33 and 39 of v1.5 and v2.0 respectively.

Instances from 0x00 through 0x5f are "system-relative", meaning unique within the context of the EntityID system-wide. Instances from 0x60 through 0x7f are "device-relative", meaning they only have to be unique within the context of the EntityID on their management controller (SDR owner). This effectively means the component (confusingly, the spec sometimes call this an "entity") is now identified by the triple (EntityID, OwnerAddress, EntityInstance) rather than (EntityID, EntityInstance). Device-relative entity instances mean devices don't have to care about collisions with each other's instance numbers, even if they are of the same EntityID.

func (EntityInstance) IsDeviceRelative

func (i EntityInstance) IsDeviceRelative() bool

IsDeviceRelative returns whether the instance is guaranteed to be unique for the entity ID only on the same management controller (i.e. owner).

func (EntityInstance) IsSystemRelative

func (i EntityInstance) IsSystemRelative() bool

IsSystemRelative returns whether the instance is guaranteed to be unique for the entity ID across all management controllers.

func (EntityInstance) String

func (i EntityInstance) String() string

String returns a human-readable representation of the instance. The spec recommends subtracting 0x60 when displaying device-relative instance values, and displaying them with the name of their controller. This implementation follows the former (it does not have access to the owner).

type FullSensorRecord

type FullSensorRecord struct {
	layers.BaseLayer
	SensorRecordKey
	ConversionFactors

	// IsContainerEntity indicates whether we should treat the entity as a
	// logical container entity, as opposed to a physical entity. This is used
	// in conjunction with Entity Association records.
	IsContainerEntity bool

	// Entity describes the type of component that the sensor monitors, e.g. a
	// processor. See EntityID for more details.
	Entity EntityID

	// Instance provides a way to distinguish between multiple occurrences of a
	// given entity, e.g. a dual socket system will likely have two processor
	// temperature sensors, each with a different instance. We can enumerate all
	// instances to ensure all processors are covered.
	Instance EntityInstance

	// Ignore indicates whether we should ignore the sensor if its entity is
	// absent or disabled. In general, this can be assumed to be true. The
	// entity's status can be obtained via an Entity Presence sensor.
	Ignore bool

	// SensorType indicates what is being measured. For analogue sensors, this
	// is the dimension, e.g. temperature. For discrete sensors, there are many
	// values to pinpoint exactly what is being exposed.
	SensorType SensorType

	// OutputType contains the Event/Reading Type Code of the underlying sensor.
	OutputType OutputType

	// AnalogDataFormat indicates whether the Reading, NormalMin, NormalMax,
	// SensorMin and SensorMax fields are unsigned, 1's complement or 2's
	// complement. This field will be AnalogDataFormatNotAnalog if the sensor
	// specifies thresholds but not numeric readings. Note it will be
	// AnalogDataFormatUnsigned if the sensor provides neither thresholds nor
	// analog readings. Identifying whether a sensor providing analog reading is
	// more an art than a science; in practice, this field alone is good enough.
	AnalogDataFormat AnalogDataFormat

	// RateUnit gives the time period throughput-based quantities are provided
	// over, e.g. airflow per second, minute, day etc.
	RateUnit RateUnit

	// IsPercentage indicates whether the reading is a percentage.
	IsPercentage bool

	// BaseUnit gives the primary unit of the sensor's reading, e.g. Celsius or
	// Fahrenheit for a temperature sensor.
	BaseUnit SensorUnit

	// ModifierUnit is contained in the Sensor Units 3 field. Note this is
	// distinct from the identically-named 2-bit field in Sensor Units 1. 0x0
	// means unused.
	ModifierUnit SensorUnit

	// Linearisation indicates whether the sensor is linear, linearised or
	// non-linear. This controls post-processing after applying the linear
	// conversion formula to the raw reading.
	Linearisation Linearisation

	// Tolerance gives the absolute accuracy of the sensor in +/- half raw
	// counts. This is a 6-bit uint on the wire.
	Tolerance uint8

	// Accuracy gives the sensor accuracy in 0.01% increments when raised to
	// AccuracyExp. This is a 10-bit int on the wire.
	Accuracy int16

	// AccuracyExp is the quantity Accuracy is raised to the power of to give
	// the final accuracy.
	AccuracyExp uint8

	// Direction indicates whether the sensor is monitoring input or output of
	// the entity.
	Direction SensorDirection

	// NominalReadingSpecified indicates whether the NominalReading field should
	// be interpreted.
	NominalReadingSpecified bool

	// NormalMinSpecified indicates whether the NormalMin field should be
	// interpreted.
	NormalMinSpecified bool

	// NormalMaxSpecified indicates whether the NormalMax field should be
	// interpreted.
	NormalMaxSpecified bool

	// NominalReading contains a sample value for the sensor. Note: this is
	// *not* the current reading. This is in the format specified by
	// AnalogDataFormat. It should be ignored if the characteristic flags
	// indicate the nominal reading is not specified.
	NominalReading uint8

	// NormalMin prints the lower threshold for normal reading range. It is in
	// the format specified by AnalogDataFormat. It should be ignored if the
	// characteristic flags indicate the normal min reading is not specified.
	NormalMin uint8

	// NormalMax prints the upper threshold for normal reading range. It is in
	// the format specified by AnalogDataFormat. It should be ignored if the
	// characteristic flags indicate the normal min reading is not specified.
	NormalMax uint8

	// SensorMin caps the lowest reading the sensor can provide. Readings lower
	// than this should be given as this value (this is not enforced).
	SensorMin uint8

	// SensorMax caps the highest reading the sensor can provide. Readings
	// higher than this should be given as this value (this is not enforced).
	SensorMax uint8

	// Identity is a descriptive string for the sensor. This can be up to 16
	// bytes long, which translates into 16-32 characters depending on the
	// format used. There are no conventions around this, and it is provided for
	// informational purposes only. Contrary to the name, attempting to identify
	// sensors based on this value is doomed to fail.
	Identity string
}

FullSensorRecord is specified in 37.1 and 43.1 of v1.5 and v2.0 respectively. It describes any type of sensor, and is the only record type that can describe a sensor generating analogue (i.e. non-enumerated/discrete) readings, e.g. a temperature sensor. It is specified as 64 bytes. This layer represents the record key and record body sections.

func (*FullSensorRecord) CanDecode

func (r *FullSensorRecord) CanDecode() gopacket.LayerClass

func (*FullSensorRecord) DecodeFromBytes

func (r *FullSensorRecord) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*FullSensorRecord) LayerType

func (*FullSensorRecord) LayerType() gopacket.LayerType

func (*FullSensorRecord) NextLayerType

func (*FullSensorRecord) NextLayerType() gopacket.LayerType

type GetChannelAuthenticationCapabilitiesCmd

type GetChannelAuthenticationCapabilitiesCmd struct {
	Req GetChannelAuthenticationCapabilitiesReq
	Rsp GetChannelAuthenticationCapabilitiesRsp
}

func (*GetChannelAuthenticationCapabilitiesCmd) Name

Name returns "Get Channel Authentication Capabilities".

func (*GetChannelAuthenticationCapabilitiesCmd) Operation

Operation returns OperationGetChannelAuthenticationCapabilitiesReq.

func (*GetChannelAuthenticationCapabilitiesCmd) RemoteLUN

func (*GetChannelAuthenticationCapabilitiesCmd) Request

func (*GetChannelAuthenticationCapabilitiesCmd) Response

type GetChannelAuthenticationCapabilitiesReq

type GetChannelAuthenticationCapabilitiesReq struct {
	layers.BaseLayer

	// ExtendedData tells the BMC we understand IPMI v2.0 and want to discover
	// extended capabilities. In this case, the response will indicate support
	// for both IPMI v2.0 and IPMI v1.5. Ignored if the BMC only understands
	// IPMI v1.5.
	ExtendedData bool

	// Channel defines the channel whose authentication capabilities to
	// retrieve. Use ChannelPresentInterface to specify the current channel.
	Channel Channel

	// MaxPrivilege level indicates the user privilege level the remote console
	// intends to use on the channel. Specifying a higher privilege level may
	// mean the managed system chooses to respond with a stricter subset of
	// capabilities.
	MaxPrivilegeLevel PrivilegeLevel
}

GetChannelAuthenticationCapabilitiesReq defines a Get Channel Authentication Capabilities request. Its wire format is specified in section 18.12 of IPMI v1.5, and 22.13 of IPMI v2.0. This command is used to retrieve authentication algorithm support for a given channel at a given privilege level. In IPMIv2, this also reveals support for IPMI v1.5. This command can be sent outside a session. Inside a session, it is normally used as a keepalive. BMC implementations of IP-based channels must support this command using the IPMI v1.5 packet format, so it makes sense to always send it using v1.5 encapsulation unless you know a-priori that the managed system supports IPMI v2.0. This command is typically the first one sent when looking to establish a session.

func (*GetChannelAuthenticationCapabilitiesReq) LayerType

func (*GetChannelAuthenticationCapabilitiesReq) SerializeTo

type GetChannelAuthenticationCapabilitiesRsp

type GetChannelAuthenticationCapabilitiesRsp struct {
	layers.BaseLayer

	// Channel is the channel number that these authentication capabilities
	// correspond to. This will never be ChannelPresentInterface.
	Channel Channel

	// ExtendedCapabilities indicates whether IPMI v2.0+ extended capabilities
	// are available. This will be false if the remote console did not request
	// extended data in its command.
	ExtendedCapabilities bool

	AuthenticationTypeOEM      bool
	AuthenticationTypePassword bool
	AuthenticationTypeMD5      bool
	AuthenticationTypeMD2      bool
	AuthenticationTypeNone     bool

	// TwoKeyLogin indicates whether the key-generating key K_G is not null.
	// This key is sometimes referred to as the "BMC Key" in the spec, however
	// this is misleading as the key "must be individually settable on each
	// channel that supports RMCP+" (22.25), so it is not global within the BMC.
	// This field applies to IPMI v2.0 only; will always be false for v1.5
	// (reserved bit).
	//
	// Two-key login is almost always disabled, as it effectively adds a second
	// password in addition to the user (or role in IPMI v2.0) password, which
	// must be known a-priori to establish a session.
	//
	// K_G is a 20 byte value used as the key for an HMAC during RMCP+ session
	// creation to produce the SIK. If K_G is null, K_[UID] (i.e. the user
	// password) is used instead. In this case, it is recommended for the user
	// password to have the 20 byte maximum length to lose as little security as
	// possible.
	TwoKeyLogin bool

	// PerMessageAuthentication being disabled means the BMC is only expecting
	// the Activate Session request to be authenticated - and likely only its
	// reply will be authenticated. Subsequent packets can use an authentication
	// type of NONE. A remote console is free to authenticate all packets it
	// sends (this one does), however the BMC can choose whether to validate
	// these, and if it is incorrect, it may still drop the packet.
	PerMessageAuthentication bool

	// UserLevelAuthentication being disabled means that commands requiring
	// only the User privilege level do not have to be authenticated,
	// regardless of PerMessageAuthentication - the idea being because these
	// commands are read-only. This library authenticates all packets
	// regardless.
	UserLevelAuthentication bool

	NonNullUsernamesEnabled bool
	NullUsernamesEnabled    bool
	AnonymousLoginEnabled   bool

	// SupportsV2 indicates whether the managed system supports IPMI v2.0 and
	// RMCP+.
	SupportsV2 bool

	// SupportsV1 indicates whether the managed system supports IPMI v1.5. Note
	// that this field was introduced in the v2.0 spec, and so will be false if
	// the BMC only supports v1.5. It is somewhat redundant if we receive this
	// response.
	SupportsV1 bool

	// OEM is the enterprise number of the organisation that specified the OEM
	// authentication type. This will be null if no such type is available,
	// displayed as "0(Unknown)".
	OEM iana.Enterprise

	// OEMData contains additional OEM-defined information for the OEM
	// authentication type. This will be null if no such type is available.
	OEMData byte
}

GetChannelAuthenticationCapabilitiesRsp represents the response to a Get Channel Authentication Capabilities request.

func (*GetChannelAuthenticationCapabilitiesRsp) CanDecode

func (*GetChannelAuthenticationCapabilitiesRsp) DecodeFromBytes

func (*GetChannelAuthenticationCapabilitiesRsp) LayerType

func (*GetChannelAuthenticationCapabilitiesRsp) NextLayerType

type GetChannelCipherSuitesCmd

type GetChannelCipherSuitesCmd struct {
	Req GetChannelCipherSuitesReq
	Rsp GetChannelCipherSuitesRsp
}

func (*GetChannelCipherSuitesCmd) Name

Name returns "Get Channel Cipher Suites".

func (*GetChannelCipherSuitesCmd) Operation

func (*GetChannelCipherSuitesCmd) Operation() *Operation

Operation returns &OperationGetChannelCipherSuitesReq.

func (*GetChannelCipherSuitesCmd) RemoteLUN

func (c *GetChannelCipherSuitesCmd) RemoteLUN() LUN

func (*GetChannelCipherSuitesCmd) Request

func (*GetChannelCipherSuitesCmd) Response

type GetChannelCipherSuitesReq

type GetChannelCipherSuitesReq struct {
	layers.BaseLayer

	// Channel defines the channel whose supported cipher suites to retrieve.
	// Use ChannelPresentInterface to specify the current channel.
	Channel Channel

	// PayloadType indicates the type of payload that will be sent over the
	// channel when the session is established, which can influence cipher
	// suite availability. This is primarily useful for OEM support. If in
	// doubt, leave as the default PayloadTypeIPMI.
	PayloadType PayloadType

	// ListIndex is the 6-bit 0-based offset (0 through 63) into the cipher
	// suite record data, which is returned 16 bytes at a time. This means the
	// total length of cipher suite records cannot exceed 1024 bytes.
	ListIndex uint8
}

GetChannelCipherSuitesReq is defined in section 22.15 of IPMI v2.0. It is used to retrieve the authentication, integrity and confidentiality algorithms supported by a given channel on the BMC. Support for this command is mandatory for IPMI v2.0 BMCs implementing sessions, and it may be sent at all privilege levels, both inside and outside a session.

The spec indicates BMCs may narrow the suites they accept at higher privilege levels (a given privilege level supports a subset of suites available at less-privileged levels), however there is no known mechanism to find out which suites apply to which privilege levels. We would expect there to be a MaxPrivilegeLevel field in this request.

func (*GetChannelCipherSuitesReq) LayerType

func (*GetChannelCipherSuitesReq) SerializeTo

type GetChannelCipherSuitesRsp

type GetChannelCipherSuitesRsp struct {
	layers.BaseLayer

	// Channel is the channel number that these cipher suites correspond to.
	// This will never be ChannelPresentInterface.
	Channel Channel

	// CipherSuiteRecordsChunk is up to 16 bytes of Cipher Suite Record data,
	// that may begin mid-way through a record, so is typically interpreted
	// after prior indices' data has been retrieved. Note this references data
	// in the decoded packet, so should be appended to a buffer before reading
	// the next packet.
	CipherSuiteRecordsChunk []byte
}

GetChannelCipherSuitesRsp represents the response to a Get Channel Cipher Suites request.

func (*GetChannelCipherSuitesRsp) CanDecode

func (*GetChannelCipherSuitesRsp) DecodeFromBytes

func (c *GetChannelCipherSuitesRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetChannelCipherSuitesRsp) LayerType

func (*GetChannelCipherSuitesRsp) NextLayerType

func (*GetChannelCipherSuitesRsp) NextLayerType() gopacket.LayerType

type GetChassisStatusCmd

type GetChassisStatusCmd struct {
	Rsp GetChassisStatusRsp
}

func (*GetChassisStatusCmd) Name

func (*GetChassisStatusCmd) Name() string

Name returns "Get Chassis Status".

func (*GetChassisStatusCmd) Operation

func (*GetChassisStatusCmd) Operation() *Operation

Operation returns OperationGetChassisStatusReq.

func (*GetChassisStatusCmd) RemoteLUN

func (*GetChassisStatusCmd) RemoteLUN() LUN

func (*GetChassisStatusCmd) Request

func (*GetChassisStatusCmd) Response

type GetChassisStatusRsp

type GetChassisStatusRsp struct {
	layers.BaseLayer

	// PowerRestorePolicy indicates what the system will do if power is lost
	// then returns.
	PowerRestorePolicy PowerRestorePolicy

	// PowerControlFault indicates whether the last attempt to change the system
	// power state failed.
	PowerControlFault bool

	// PowerFault indicates whether a fault has been detected in the main power
	// subsystem.
	PowerFault bool

	// Interlock indicates whether the last system shutdown was caused by the
	// activation of a chassis panel interlock switch.
	Interlock bool

	// PowerOverload indicates whether the last system shutdown was caused by a
	// power overload.
	PowerOverload bool

	// PoweredOn indicates whether the system power is on. If false, the system
	// could be in S4/S5, or mechanical off.
	PoweredOn bool

	// PoweredOnByIPMI indicates whether the last command to turn on the system
	// was issued via IPMI.
	PoweredOnByIPMI bool

	// LastPowerDownFault indicates whether the last power down was caused by a
	// power fault.
	LastPowerDownFault bool

	// LastPowerDownInterlock indicates whether the last power down was caused
	// by the activation of a chassis panel interlock switch.
	LastPowerDownInterlock bool

	// LastPowerDownOverload indicates whether the last power down was caused by
	// a power overload.
	LastPowerDownOverload bool

	// LastPowerDownSupplyFailure indicates whether the last power down was
	// caused by an interruption in mains power to the system (not a PSU
	// failure).
	LastPowerDownSupplyFailure bool

	// ChassisIdentifyState indicates the current state of the chassis
	// identification mechanism.
	ChassisIdentifyState ChassisIdentifyState

	// CoolingFault indicates whether a cooling or fan fault has been detected.
	CoolingFault bool

	// DriveFault indicates whether a disk drive in the system is faulty.
	DriveFault bool

	// Lockout indicates whether both power off and reset via the chassis
	// buttons is disabled.
	Lockout bool

	// Intrusion indicates a chassis intrusion is active.
	Intrusion bool

	// StandbyButtonDisableAllowed indicates whether the chassis allows
	// disabling the standby/sleep button.
	StandbyButtonDisableAllowed bool

	// DiagnosticInterruptButtonDisableAllowed indicates whether the chassis
	// allows disabling the diagnostic interrupt button.
	DiagnosticInterruptButtonDisableAllowed bool

	// ResetButtonDisableAllowed indicates whether the chassis allows disabling
	// the reset button.
	ResetButtonDisableAllowed bool

	// PowerOffButtonDisableAllowed indicates whether the chassis allows
	// disabling the power off button. If the button also controls sleep, this
	// being true indicates that sleep requests via the same button can also be
	// disabled.
	PowerOffButtonDisableAllowed bool

	// StandbyButtonDisabled indicates whether the chassis' standby/sleep
	// button is currently disabled.
	StandbyButtonDisabled bool

	// DiagnosticInterruptButtonDisabled indicates whether the chassis'
	// diagnostic interrupt button is currently disabled.
	DiagnosticInterruptButtonDisabled bool

	// ResetButtonDisableAllowed indicates whether the chassis' reset button is
	// currently disabled.
	ResetButtonDisabled bool

	// PowerOffButtonDisabled indicates whether the chassis' power off button
	// is currently disabled. If the button also controls sleep, this being true
	// indicates that sleep requests via the same button are also disabled.
	PowerOffButtonDisabled bool
}

GetChassisStatusRsp represents the managed system's response to a Get Chassis Status command, specified in 22.2 and 28.2 of IPMI v1.5 and v2.0 respectively.

func (*GetChassisStatusRsp) CanDecode

func (s *GetChassisStatusRsp) CanDecode() gopacket.LayerClass

func (*GetChassisStatusRsp) DecodeFromBytes

func (s *GetChassisStatusRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetChassisStatusRsp) LayerType

func (*GetChassisStatusRsp) LayerType() gopacket.LayerType

func (*GetChassisStatusRsp) NextLayerType

func (*GetChassisStatusRsp) NextLayerType() gopacket.LayerType

type GetDeviceIDCmd

type GetDeviceIDCmd struct {
	Rsp GetDeviceIDRsp
}

func (*GetDeviceIDCmd) Name

func (*GetDeviceIDCmd) Name() string

Name returns "Get Device ID".

func (*GetDeviceIDCmd) Operation

func (*GetDeviceIDCmd) Operation() *Operation

Operation returns OperationGetDeviceIDReq.

func (*GetDeviceIDCmd) RemoteLUN

func (c *GetDeviceIDCmd) RemoteLUN() LUN

func (*GetDeviceIDCmd) Request

func (*GetDeviceIDCmd) Response

func (c *GetDeviceIDCmd) Response() gopacket.DecodingLayer

type GetDeviceIDRsp

type GetDeviceIDRsp struct {
	layers.BaseLayer

	// ID is the device ID. 0x00 means unspecified.
	ID uint8

	// ProvidesSDRs indicates whether the device provides Device SDRs.
	ProvidesSDRs bool

	// Revision contains the device revision. This is a 4-bit uint on the wire.
	Revision uint8

	// Available is true if the device is under normal operation - that is, not
	// performing an SDR repository update, firmware update or
	// self-initialisation. The first two can be distinguished by issuing Get
	// SDR and looking at the completion code.
	Available bool

	// MajorFirmwareRevision is a 6-bit uint on the wire.
	MajorFirmwareRevision uint8

	MinorFirmwareRevision uint8

	// MajorIPMIVersion is the integral component of the IPMI specification
	// implemented by the BMC. This is not influenced by whether the Get Device
	// ID command was executed using a v1.5 session wrapper.
	MajorIPMIVersion uint8
	MinorIPMIVersion uint8

	SupportsChassisDevice            bool
	SupportsBridgeDevice             bool
	SupportsIPMBEventGeneratorDevice bool
	SupportsIPMBEventReceiverDevice  bool
	SupportsFRUInventoryDevice       bool
	SupportsSELDevice                bool
	SupportsSDRRepositoryDevice      bool
	SupportsSensorDevice             bool

	// Manufacturer is sometimes that of the BMC (Intel) or that of the
	// motherboard (SuperMicro, which uses an Aten BMC...). It is a 20-bit uint
	// on the wire; the most significant 4 bits are reserved, set to 0000b.
	// 0x000000 means unspecified.
	Manufacturer iana.Enterprise

	// Product is chosen by the manufacturer to identify a particular system,
	// module, add-in card or board set. 0x0000 means unspecified. This is not
	// reliable; it has observed to be the same on different Quanta models.
	Product uint16

	AuxiliaryFirmwareRevision [4]byte
}

GetDeviceIDRsp represents the response to a Get Device ID command, specified in 17.1 of IPMI v1.5 and 20.1 of IPMI v2.0.

func (*GetDeviceIDRsp) CanDecode

func (g *GetDeviceIDRsp) CanDecode() gopacket.LayerClass

func (*GetDeviceIDRsp) DecodeFromBytes

func (g *GetDeviceIDRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetDeviceIDRsp) LayerType

func (*GetDeviceIDRsp) LayerType() gopacket.LayerType

func (*GetDeviceIDRsp) NextLayerType

func (*GetDeviceIDRsp) NextLayerType() gopacket.LayerType

type GetSDRCmd

type GetSDRCmd struct {
	Req GetSDRReq
	Rsp GetSDRRsp
}

func (*GetSDRCmd) Name

func (*GetSDRCmd) Name() string

Name returns "Get SDR".

func (*GetSDRCmd) Operation

func (*GetSDRCmd) Operation() *Operation

Operation returns &OperationGetSDRReq.

func (*GetSDRCmd) RemoteLUN

func (c *GetSDRCmd) RemoteLUN() LUN

func (*GetSDRCmd) Request

func (c *GetSDRCmd) Request() gopacket.SerializableLayer

func (*GetSDRCmd) Response

func (c *GetSDRCmd) Response() gopacket.DecodingLayer

type GetSDRRepositoryInfoCmd

type GetSDRRepositoryInfoCmd struct {
	Rsp GetSDRRepositoryInfoRsp
}

func (*GetSDRRepositoryInfoCmd) Name

Name returns "Get SDR Repository Info".

func (*GetSDRRepositoryInfoCmd) Operation

func (*GetSDRRepositoryInfoCmd) Operation() *Operation

Operation returns OperationGetSDRRepositoryInfoReq.

func (*GetSDRRepositoryInfoCmd) RemoteLUN

func (*GetSDRRepositoryInfoCmd) RemoteLUN() LUN

func (*GetSDRRepositoryInfoCmd) Request

func (*GetSDRRepositoryInfoCmd) Response

type GetSDRRepositoryInfoRsp

type GetSDRRepositoryInfoRsp struct {
	layers.BaseLayer

	// Version indicates the command set supported by the SDR Repository Device.
	// This is little-endian packed BCD, and has not changed from 0x51 (i.e.
	// IPMI v1.5) since IPMI-over-LAN was introduced in v1.5.
	Version uint8

	// Records is the number of records in the SDR repository.
	Records uint16

	// FreeSpace is the space remaining in the SDR repository in bytes.
	FreeSpace uint16

	// LastAddition is the time when the last record was added to the
	// repository. This will be the zero value if never.
	LastAddition time.Time

	// LastErase is the time when the last record was deleted from the
	// repository, or the entire repository was cleared. This will be the zero
	// value if never.
	LastErase time.Time

	// Overflow indicates whether an SDR could not be written due to lack of
	// space.
	Overflow bool

	// SupportsModalUpdate indicates whether the controller must be put in an
	// SDR Repository update mode in order to be modified. False means
	// unspecified rather than unsupported, in which case the remote console
	// should attempt a Enter SDR Update Mode before falling back to a non-modal
	// update. If this is false and SupportsNonModalUpdate is true, a non-modal
	// update should be performed.
	SupportsModalUpdate bool

	// SupportsNonModalUpdate indicates whether the controller can be written to
	// at any time, without impacting other commands. False means unspecified
	// rather than unsupported; if SupportsModalUpdate is true, a modal update
	// should be performed.
	SupportsNonModalUpdate bool

	// SupportsDelete indicates whether the Delete SDR command is supported.
	SupportsDelete bool

	// SupportsPartialAdd indicates whether the Partial Add SDR command is
	// supported.
	SupportsPartialAdd bool

	// SupportsReserve indicates whether the Reserve SDR Repository command is
	// supported.
	SupportsReserve bool

	// SupportsGetAllocationInformation indicates whether the Get SDR Repository
	// Allocation Information command is supported.
	SupportsGetAllocationInformation bool
}

GetSDRRepositoryInfoRsp represents the response to a Get SDR Repository Info command, specified in section 27.9 and 33.9 of IPMI v1.5 and v2.0 respectively. This command is useful for finding out how many SDRs are in the repository, and finding whether any changes were made during enumeration (meaning a re-retrieval is required).

func (*GetSDRRepositoryInfoRsp) CanDecode

func (*GetSDRRepositoryInfoRsp) DecodeFromBytes

func (i *GetSDRRepositoryInfoRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetSDRRepositoryInfoRsp) LayerType

func (*GetSDRRepositoryInfoRsp) NextLayerType

func (*GetSDRRepositoryInfoRsp) NextLayerType() gopacket.LayerType

type GetSDRReq

type GetSDRReq struct {
	layers.BaseLayer

	// ReservationID is a consistency token, required if Offset > 0. If
	// provided, the request will fail if the SDR Repo device believes any
	// Record IDs that existed before the reservation was created may have
	// changed.
	ReservationID ReservationID

	// RecordID is the unique identifier of the SDR to read. To read the first
	// record, specify RecordIDFirst.
	RecordID RecordID

	// Offset is the number of bytes into the record to start reading from. If
	// >0, ReservationID must be non-zero.
	Offset uint8

	// Length is the number of bytes to read starting at the offset. Note that
	// 0xff is a sentinel value. It doesn't mean 255 bytes, it means the entire
	// record. Apparently this is more than most buffer sizes, so in "most
	// cases", will cause the BMC to return 0xca (or 0xff - it should be
	// interpreted the same in this case) as the completion code.
	Length uint8
}

GetSDRReq represents a request to retrieve a single Sensor Data Record from the BMC's SDR Repository Device. This command is specified in section 27.12 and 33.12 of IPMI v1.5 and 2.0 respectively.

No guarantees are made about the ordering of returned SDRs. Record IDs tend to be returned in ascending order, but have big gaps between numbers. The underlying entities and instances are scrambled - it cannot be assumed that when the next SDR has a different entity, there is no more of the current entity. The specification recommends retrieving all SDRs and incrementally indexing or processing them as needed.

func (*GetSDRReq) LayerType

func (*GetSDRReq) LayerType() gopacket.LayerType

func (*GetSDRReq) SerializeTo

type GetSDRRsp

type GetSDRRsp struct {
	layers.BaseLayer

	// Next is the Record ID of the "next" record in the SDR repository. If the
	// current record has RecordIDLast, and this is equal to RecordIDLast, the
	// end of the repository has been reached.
	Next RecordID
}

GetSDRRsp contains the next Record ID in the SDR Repo, and wraps the SDR data requested.

func (*GetSDRRsp) CanDecode

func (s *GetSDRRsp) CanDecode() gopacket.LayerClass

func (*GetSDRRsp) DecodeFromBytes

func (s *GetSDRRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetSDRRsp) LayerType

func (*GetSDRRsp) LayerType() gopacket.LayerType

func (*GetSDRRsp) NextLayerType

func (*GetSDRRsp) NextLayerType() gopacket.LayerType

type GetSensorReadingCmd

type GetSensorReadingCmd struct {
	Req GetSensorReadingReq
	Rsp GetSensorReadingRsp

	// OwnerLUN is the remote LUN of the sensor being retrieved. We learn this
	// from the SDR.
	OwnerLUN LUN
}

func (*GetSensorReadingCmd) Name

func (*GetSensorReadingCmd) Name() string

Name returns "Get Sensor Reading".

func (*GetSensorReadingCmd) Operation

func (*GetSensorReadingCmd) Operation() *Operation

Operation returns &OperationGetSensorReadingReq.

func (*GetSensorReadingCmd) RemoteLUN

func (c *GetSensorReadingCmd) RemoteLUN() LUN

func (*GetSensorReadingCmd) Request

func (*GetSensorReadingCmd) Response

type GetSensorReadingReq

type GetSensorReadingReq struct {
	layers.BaseLayer

	// Number is the number of the sensor whose reading to retrieve. The sensor
	// number is specified in an SDR returned by the BMC. 0xff is reserved.
	Number uint8
}

GetSensorReadingReq represents a Get Sensor Reading command, specified in 29.14 and 35.14 of v1.5 and v2.0 respectively.

func (*GetSensorReadingReq) LayerType

func (*GetSensorReadingReq) LayerType() gopacket.LayerType

func (*GetSensorReadingReq) SerializeTo

type GetSensorReadingRsp

type GetSensorReadingRsp struct {
	layers.BaseLayer

	// Reading is the raw reading value, which can be unsigned, 1's complement
	// or 2's complement. A suitable AnalogDataFormatConverter implementation
	// can be obtained by calling .AnalogDataFormat.Converter() on
	// FullSensorRecord. If the sensor does not return a numeric reading or
	// ReadingUnavailable is set, this should be ignored.
	Reading byte

	// EventMessagesEnabled indicates whether all Event Messages are enabled for
	// the sensor.
	EventMessagesEnabled bool

	// ScanningEnabled indicates whether sensor scanning is enabled
	ScanningEnabled bool

	// ReadingUnavailable is used by some BMCs to indicate a sensor update is in
	// progress, or that the entity is not present. If set, the reading should
	// be ignored.
	ReadingUnavailable bool
}

func (*GetSensorReadingRsp) CanDecode

func (r *GetSensorReadingRsp) CanDecode() gopacket.LayerClass

func (*GetSensorReadingRsp) DecodeFromBytes

func (r *GetSensorReadingRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetSensorReadingRsp) LayerType

func (*GetSensorReadingRsp) LayerType() gopacket.LayerType

func (*GetSensorReadingRsp) NextLayerType

func (*GetSensorReadingRsp) NextLayerType() gopacket.LayerType

type GetSessionInfoCmd

type GetSessionInfoCmd struct {
	Req GetSessionInfoReq
	Rsp GetSessionInfoRsp
}

func (*GetSessionInfoCmd) Name

func (*GetSessionInfoCmd) Name() string

Name returns "Get Session Info".

func (*GetSessionInfoCmd) Operation

func (*GetSessionInfoCmd) Operation() *Operation

Operation returns &OperationGetSessionInfoReq.

func (*GetSessionInfoCmd) RemoteLUN

func (c *GetSessionInfoCmd) RemoteLUN() LUN

func (*GetSessionInfoCmd) Request

func (*GetSessionInfoCmd) Response

type GetSessionInfoReq

type GetSessionInfoReq struct {
	layers.BaseLayer

	// Index is an offset into the logical sessions table maintained by the BMC.
	// Active sessions can be enumerated by incrementing this from 1 through to
	// the Active field of the response.
	Index SessionIndex

	// Handle is the handle of the session to request information for. This is
	// similar to the session ID, but only unique within the context of a
	// channel. See type SessionHandle for more details.
	Handle SessionHandle

	// ID is the ID of the session to request information for. For IPMI v2.0,
	// this is the ID assigned by the BMC, i.e. RemoteID, not the one generated
	// by the remote console.
	ID uint32
}

GetSessionInfoReq represents a Get Session Info request, specified in section 18.18 and 22.20 of IPMI v1.5 and v2.0 respectively. A session can be identified by one of its index, handle or ID. To get the current session, pass the zero-value. If identifying by handle, set Index to SessionIndexHandle. If identifying by ID, set Index to SessionIndexID.

func (*GetSessionInfoReq) LayerType

func (*GetSessionInfoReq) LayerType() gopacket.LayerType

func (*GetSessionInfoReq) SerializeTo

type GetSessionInfoRsp

type GetSessionInfoRsp struct {
	layers.BaseLayer

	// Handle is the session handle of the requested session. In theory, this
	// should be 0x00 if no active session was found matching the coordinates in
	// the request, in which case only the Max and Active fields are valid. In
	// practice, Super Micro BMCs send a handle of 0x00 but then include
	// additional fields as if the session were valid. Checking UserID != 0 is a
	// more robust way to check if it and subsequent fields were included in the
	// response.
	Handle SessionHandle

	// Max is the highest number of simultaneous active sessions supported by
	// the BMC. This is independent of the session coordinates specified in the
	// request. It is a 6-bit uint on the wire.
	Max uint8

	// Active is the number of currently active sessions, <= Max. It is a 6-bit
	// uint on the wire. 0 means there are no active sessions.
	Active uint8

	// UserID is the ID of the user for the selected session. It is only
	// relevant if Handle is non-zero. This is a 6-bit uint on the wire. Zero
	// is reserved, and indicates no session was found.
	UserID uint8

	// PrivilegeLevel indicates the operating privilege level of the user in the
	// active session.
	PrivilegeLevel PrivilegeLevel

	// IsIPMIv2 applies to remote sessions, and indicates whether IPMI v1.5 or
	// v2.0 is in use. If this is true, it guarantees a LAN session.
	IsIPMIv2 bool

	// Channel is the channel number the session was activated over.
	Channel Channel

	// IP is the source IP address of the Activate Session command in IPMI v1.5,
	// or (presumably, to be consistent with Port) the RAKP Message 3 in IPMI
	// v2.0. This is 4 bytes on the wire; it is unclear what this will be if
	// communicating with the BMC over IPv6. This only applies to LAN sessions,
	// and the BMC is not required by the spec to store this.
	IP net.IP

	// MAC is the source MAC Address of the same packet used to populate IP. It
	// only applies to LAN sessions, and the BMC is not required by the spec to
	// store this.
	MAC net.HardwareAddr

	// Port is the source port number of the same packet used to populate IP. It
	// only applies to LAN sessions, and the BMC is not required by the spec to
	// store this.
	Port uint16
}

func (*GetSessionInfoRsp) CanDecode

func (g *GetSessionInfoRsp) CanDecode() gopacket.LayerClass

func (*GetSessionInfoRsp) DecodeFromBytes

func (g *GetSessionInfoRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetSessionInfoRsp) LayerType

func (*GetSessionInfoRsp) LayerType() gopacket.LayerType

func (*GetSessionInfoRsp) NextLayerType

func (*GetSessionInfoRsp) NextLayerType() gopacket.LayerType

type GetSystemGUIDCmd

type GetSystemGUIDCmd struct {
	Rsp GetSystemGUIDRsp
}

func (*GetSystemGUIDCmd) Name

func (*GetSystemGUIDCmd) Name() string

Name returns "Get System GUID".

func (*GetSystemGUIDCmd) Operation

func (*GetSystemGUIDCmd) Operation() *Operation

Operation returns OperationGetSystemGUIDReq.

func (*GetSystemGUIDCmd) RemoteLUN

func (*GetSystemGUIDCmd) RemoteLUN() LUN

func (*GetSystemGUIDCmd) Request

func (*GetSystemGUIDCmd) Response

func (c *GetSystemGUIDCmd) Response() gopacket.DecodingLayer

type GetSystemGUIDRsp

type GetSystemGUIDRsp struct {
	layers.BaseLayer

	// GUID contains the BMC's globally unique ID in the original byte order.
	// This can be in any format, and any byte order, so cannot be interpreted
	// reliably without additional knowledge. As an approximation, treating the
	// original bytes as a GUID seems to work fairly well; on Dell this matches
	// the smbiosGUID field in the iDRAC UI, and on Quanta it produces a valid
	// version 1 GUID.
	GUID [16]byte
}

GetSystemGUIDRsp is the response to a Get System GUID command, specified in 18.13 and 22.14 of IPMI v1.5 and 2.0 respectively.

func (*GetSystemGUIDRsp) CanDecode

func (g *GetSystemGUIDRsp) CanDecode() gopacket.LayerClass

func (*GetSystemGUIDRsp) DecodeFromBytes

func (g *GetSystemGUIDRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*GetSystemGUIDRsp) LayerType

func (*GetSystemGUIDRsp) LayerType() gopacket.LayerType

func (*GetSystemGUIDRsp) NextLayerType

func (*GetSystemGUIDRsp) NextLayerType() gopacket.LayerType

type IntegrityAlgorithm

type IntegrityAlgorithm uint8

IntegrityAlgorithm is the 6-bit identifier of an integrity algorithm negotiated during the RMCP+ session establishment process. The numbers are defined in 13.28.4 of the spec. The integrity algorithm is used to calculate the signature for authenticated RMCP+ messages.

const (
	IntegrityAlgorithmNone          IntegrityAlgorithm = iota
	IntegrityAlgorithmHMACSHA196                       // 12 byte authcode
	IntegrityAlgorithmHMACMD5128                       // 16 bytes ”
	IntegrityAlgorithmMD5128                           // 16 bytes ”
	IntegrityAlgorithmHMACSHA256128                    // 16 bytes ”
)

func (IntegrityAlgorithm) String

func (i IntegrityAlgorithm) String() string

type IntegrityPayload

type IntegrityPayload struct {

	// Wildcard asks the BMC to choose an algorithm based on the requested max
	// privilege level. If this is true, Algorithm is null.
	Wildcard bool

	// Algorithm is the integrity algorithm to indicate support for. If
	// this is non-null, Wildcard is false.
	Algorithm IntegrityAlgorithm
}

IntegrityPayload indicates a single integrity algorithm preference embedded in an RMCP+ Open Session Request message. One or more of these may be specified to indicate support for multiple algorithms, however this is uncommon (there is no mechanism in OpenIPMI for multiple payloads of a given type).

func (*IntegrityPayload) Deserialise

func (i *IntegrityPayload) Deserialise(d []byte, df gopacket.DecodeFeedback) ([]byte, error)

Deserialise reads an integrity payload from the supplied byte slice, returning unconsumed remaining bytes representing other payloads. If the payload is invalid, a nil slice is returned, and the payload is left in an unspecified state.

func (*IntegrityPayload) Serialise

Serialise encodes the integrity payload onto the end of a buffer, returning an error if one occurs.

type LUN

type LUN uint8

LUN represents a Logical Unit Number. It can be thought of as a sub-address within a given slave address (i.e. a sub-interface of the BMC, reachable via IPMB). It is meaningless in the context of software IDs. This is a two-bit field. See section 7.2 of IPMI v1.5 and v2.0 for value definitions. It is a 2-bit uint on the wire.

const (
	LUNBMC LUN = 0x0 // both requests and responses
	LUNSMS LUN = 0x2
)

func (LUN) String

func (l LUN) String() string

type Linearisation

type Linearisation uint8

Linearisation indicates whether a sensor is linear, linearised, or non-linear. Values are specified in the Full Sensor Record wire format table in 37-1 and 43-1 of v1.5 and v2.0 respectively.

Linear sensors are the easiest to deal with. The sensor's raw readings are converted into real readings (e.g. Celsius) with a linear formula. Accuracy and resolution are constant in real terms across the entire range of values produced by the sensor.

Linearised are slightly more challenging. The same linear formula is applied as for linear sensors, however a final "linearisation formula" is applied to obtain the real reading. This transformation is one of 11 defined in the spec, e.g. log or sqrt, and obviously does not have to be linear itself. The tolerance (the spec misuses accuracy as a synonym) of linearised sensors is also constant for all values. This is possible despite the existence of the linearisation formula turning raw values into disproportionate real values, as tolerance is expressed relative to 0. This assumes the sensor's tolerance does not diminish in real, absolute terms at extreme values (positive or negative), as there is no way of representing it (you'd have to resort to declaring it a non-linear sensor). Note that tolerance can only be expressed in half-raw value increments, which is in itself quite coarse. Regarding resolution, this will vary with reading due to the linearisation formula. The recommended way to calculate it is to retrieve and calculate the real values (with the help of Get Sensor Reading Factors as necessary) corresponding to the raw values below and above the actual raw value observed. Subtracting the real reading for the raw value below the observed raw value from the real reading for the observed value gives the negative resolution, and the process is equivalent for the positive resolution using the raw value one above.

All consistency bets are off with non-linear sensors. Not only does resolution vary by reading (calculated in the same was as for linearised sensors), but so does tolerance. Get Sensor Reading Factors must be sent with each raw reading; applying the linear formula using the returned conversion factors yields the real reading, and can the same factors can be plugged into the tolerance and resolution formulae to calculate them.

const (
	LinearisationLinear Linearisation = iota
	LinearisationLn
	LinearisationLog10
	LinearisationLog2
	LinearisationE
	LinearisationExp10
	LinearisationExp2
	LinearisationInverse
	LinearisationSqr
	LinearisationCube
	LinearisationSqrt
	LinearisationCubeRt
	LinearisationNonLinear
)

func (Linearisation) Description

func (l Linearisation) Description() string

func (Linearisation) IsLinear

func (l Linearisation) IsLinear() bool

IsLinear returns whether the underlying sensor is linear. Calling Lineariser() will return an error, as there is no linearisation formula (it is effectively a no-op). Only the linear formula in the spec needs be applied to obtain a real reading.

func (Linearisation) IsLinearised

func (l Linearisation) IsLinearised() bool

IsLinearised returns whether the underlying sensor is linearised, meaning the value after conversion needs to be fed through a linearisation formula as a final step before being used. A suitable implementation of this function is returned by the Lineariser() method.

func (Linearisation) IsNonLinear

func (l Linearisation) IsNonLinear() bool

IsNonLinear returns whether the underlying sensor is not consistent enough for the constraints of linear and linearised. As for linear sensors, attempting to retrieve a Lineariser will return an error. Readings from these sensors require Get Sensor Reading Factors to convert them into usable values.

func (Linearisation) Lineariser

func (l Linearisation) Lineariser() (Lineariser, error)

Lineariser returns a suitable Lineariser implementation that will turn the converted raw value produced by the underlying sensor into a usable value. If the sensor is already linear, or non-linear, this will return ErrNotLinearised.

func (Linearisation) String

func (l Linearisation) String() string

type Lineariser

type Lineariser interface {

	// Linearise applies a linearisation formula to a converted value, returning
	// the final value in the correct unit. This is the last step in the "Sensor
	// Reading Conversion Formula" described in section 30.3 of IPMI v1.5 and
	// v2.0.
	Linearise(float64) float64
}

Lineariser is implemented by formulae that can linearise a value returned by the Get Sensor Reading command that has gone through the linear formula containing M, B, K1 and K2, used for all sensors.

type LineariserFunc

type LineariserFunc func(float64) float64

LineariserFunc is the type of the function in the Lineariser interface. It allows us to create stateless Lineariser implementations from raw functions, including those in the math package.

func (LineariserFunc) Linearise

func (l LineariserFunc) Linearise(f float64) float64

Linearise invokes the wrapped function, passing through the input and result.

type Message

type Message struct {
	layers.BaseLayer

	// Operation encapsulates the network function and command fields.
	Operation

	// RemoteAddress is the slave address or software ID of the responder if
	// this is a request, or requester if this is a response. The
	// least-significant bit dictates the type. This will always be 0x20 when
	// the BMC is the responder (slave address 0x10).
	RemoteAddress Address

	// RemoteLUN is the logical unit number of the responder if this is a
	// request, or requester if this is a response. In practice, this will
	// almost always be 0 (BMC commands).
	RemoteLUN LUN

	// Checksum1 is a checksum over the two bytes that make up the  remote
	// address, remote LUN and function code fields. This will be calculated
	// automatically if FixChecksums is set to true in the serialise options. If
	// this checksum is incorrect, the BMC drops the packet.
	Checksum1 uint8

	// LocalAddress is the slave address or software ID of the responder if this
	// is a response, or requester if this is a request.
	LocalAddress Address

	// LocalLUN is the logical unit number of the requester if this is a
	// request, or responder if this is a response.
	LocalLUN LUN

	// Sequence is the sequence number of the message. This is used for matching
	// up responses with requests. It is a 6-bit uint on the wire.
	Sequence uint8

	// CompletionCode indicates whether a request message completed
	// successfully. This will be 0 if the message is a request. This is in the
	// message layer as it dictates whether the data layer can be decoded. A
	// side effect is that response layers are all one byte shorter than the
	// specification would indicate, and handling for this value does not have
	// to be done in every one of their decode methods - indeed, it means we
	// don't have to implement DecodingLayer for commands that return only a
	// completion code, like Close Session.
	CompletionCode

	// Checksum2 is a checksum over the local address, local LUN, sequence
	// number and command. If this checksum is incorrect, the BMC drops the
	// packet.
	Checksum2 uint8
}

Message represents an IPMI message, specified in 12.4 of the v1.5 spec and 13.8 of the v2.0 spec. This is the layer within v1.5 sessions, and within v2.0 sessions with the "IPMI" payload type. It carries addressing information and command identification for processing of the next layer, which is either a request or response.

Wire format of a request (offsets in square brackets):

  1. [0] Responder address (1 byte) - LSB determines the type: 0 for slave address, 1 for software ID. - Remaining 7 bits hold the value. - Always 0x20 when the BMC is the responder (slave address 16).
  2. [1] Network Function Code (most-significant 6 bits) - Always even for a request.
  3. Responder's LUN (least-significant 2 bits) - 00 for BMC commands.
  4. [2] Checksum (1 byte)
  5. [3] Requester's Address (1 byte) - Same as for responder address. - Again, always 0x20 when the BMC is the requester (slave address 16).
  6. [4] Sequence Number (most-significant 6 bits) - Generated by requester, mirrored in response.
  7. Requester's LUN (least-significant 2 bits) - 00 for BMC commands.
  8. [5] Command (1 byte) - e.g. Get System GUID is 0x37
  9. [6] Request Data - If a response, the first byte is the completion code. - If NetFn is Group/OEM, next byte is body code, else if NetFn is OEM, next 3 bytes are the OEM's enterprise number.
  10. [last] Checksum from [3] onwards (1 byte)

This struct has been generalised to cater for both requests and responses; in the case of a request, Remote* fields correspond to responder attributes and Local* fields correspond to requester attributes, and vice-versa in the case of responses. Note that Local* is therefore not always the remote console. The BMC is also perfectly entitled to send request messages. Requests and responses were combined to reduce code duplication - the only field that differs between them is the existence of a completion code in responses.

func (*Message) CanDecode

func (m *Message) CanDecode() gopacket.LayerClass

func (*Message) DecodeFromBytes

func (m *Message) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*Message) LayerType

func (*Message) LayerType() gopacket.LayerType

func (*Message) NextLayerType

func (m *Message) NextLayerType() gopacket.LayerType

func (*Message) SerializeTo

type NetworkFunction

type NetworkFunction uint8

NetworkFunction is a network function code, or "NetFn". This identifies the functional class of a message, e.g. chassis device, sensor readings, firmware transfer etc. It can be thought of as the category for the command. For IPMB, each class has an adjacent pair of function codes, where the lower (even) number is used for requests and the upper (odd) number is used for responses to those requests. This is a 6-bit uint on the wire. See section 5.1 of the v1.5 or v2.0 spec for definitions.

For example, Get System GUID's network function is "App", which corresponds to 0x6 and 0x7. If sending a request to the BMC, we would set our NetFn to 0x6.

const (
	NetworkFunctionChassisReq NetworkFunction = 0x0
	NetworkFunctionChassisRsp NetworkFunction = 0x1

	NetworkFunctionBridgeReq NetworkFunction = 0x2
	NetworkFunctionBridgeRsp NetworkFunction = 0x3

	NetworkFunctionSensorReq NetworkFunction = 0x4
	NetworkFunctionSensorRsp NetworkFunction = 0x5

	NetworkFunctionAppReq NetworkFunction = 0x6
	NetworkFunctionAppRsp NetworkFunction = 0x7

	NetworkFunctionFirmwareReq NetworkFunction = 0x8
	NetworkFunctionFirmwareRsp NetworkFunction = 0x9

	NetworkFunctionStorageReq NetworkFunction = 0xa
	NetworkFunctionStorageRsp NetworkFunction = 0xb

	NetworkFunctionTransportReq NetworkFunction = 0xc
	NetworkFunctionTransportRsp NetworkFunction = 0xd

	NetworkFunctionGroupReq NetworkFunction = 0x2c
	NetworkFunctionGroupRsp NetworkFunction = 0x2d

	NetworkFunctionOEMReq NetworkFunction = 0x2e
	NetworkFunctionOEMRsp NetworkFunction = 0x2f
)

func (NetworkFunction) IsRequest

func (n NetworkFunction) IsRequest() bool

IsRequest indicates whether the given network function code is used for request or response messages.

func (NetworkFunction) String

func (n NetworkFunction) String() string

type OpenSessionPayload

type OpenSessionPayload struct {
	Req OpenSessionReq
	Rsp OpenSessionRsp
}

func (*OpenSessionPayload) Descriptor

func (*OpenSessionPayload) Descriptor() *PayloadDescriptor

Descriptor returns PayloadDescriptorOpenSessionReq.

func (*OpenSessionPayload) Request

func (*OpenSessionPayload) Response

type OpenSessionReq

type OpenSessionReq struct {
	layers.BaseLayer

	// Tag is copied into the BMC's Open Session Response message to help the
	// remote console match it up with this request. If the remote console
	// retries this message, it should increment this.
	Tag uint8

	// MaxPrivilegeLevel is the highest privilege level the remote console wants
	// the BMC to allow for the session. If this is 0x0 (Highest), the BMC will
	// give us the highest level it is willing to, given the cipher suites the
	// remote console indicated support for.
	MaxPrivilegeLevel PrivilegeLevel

	// SessionID is what the remote console wants the BMC to use to identify
	// packets sent to it for this session. This should not be null, to avoid
	// conflicting with out-of-session messaging. N.B. this is not what the
	// remote console uses to send packets to the BMC.
	SessionID uint32

	// AuthenticationPayload indicates the authentication algorithm, if any, to
	// use for the session.
	AuthenticationPayload AuthenticationPayload

	// IntegrityPayload indicates the integrity algorithm, if any, to use for
	// the session.
	IntegrityPayload IntegrityPayload

	// ConfidentialityPayload indicates the confidentiality algorithm, if any,
	// to use for the session.
	ConfidentialityPayload ConfidentialityPayload
}

OpenSessionReq represents an RMCP+ Open Session Request message, specified in section 13.17.

func (*OpenSessionReq) LayerType

func (*OpenSessionReq) LayerType() gopacket.LayerType

func (*OpenSessionReq) SerializeTo

type OpenSessionRsp

type OpenSessionRsp struct {
	layers.BaseLayer

	// Tag is the tag passed in the request, to ease matching up the response.
	Tag uint8

	// Status is the RMCP+ status code indicating whether the BMC was able to
	// service the request.
	Status StatusCode

	// MaxPrivilegeLevel is the Maximum Privilege Level allowed for the
	// session based on the security algorithms that were proposed in the
	// request. It will be 0 if the status is not OK.
	MaxPrivilegeLevel PrivilegeLevel

	// RemoteConsoleSessionID is an echo of the session ID the remote console
	// asked the BMC to use in its request.
	RemoteConsoleSessionID uint32

	// ManagedSystemSessionID is the session ID the BMC would like the remote
	// console to use when sending it messages for this session. This will not
	// be null, as that would conflict with out-of-session messaging.
	ManagedSystemSessionID uint32

	// AuthenticationPayload contains the authentication algorithm selected by
	// the managed system for the session. This should not be a wildcard or
	// none, but this is not validated.
	AuthenticationPayload AuthenticationPayload

	// IntegrityPayload contains the integrity algorithm selected by the managed
	// system for the session. This should not be a wildcard or none, but this
	// is not validated.
	IntegrityPayload IntegrityPayload

	// ConfidentialityPayload contains the confidentiality algorithm selected by
	// the managed system for the session. This should not be a wildcard or
	// none, but this is not validated.
	ConfidentialityPayload ConfidentialityPayload
}

OpenSessionRsp represents an RMCP+ Open Session Response message, specified in section 13.18. This is distinct from the RAKP messages, partly because even if a RAKP message fails, the open session request and response does not have to be repeated, as they are stateless.

func (*OpenSessionRsp) CanDecode

func (o *OpenSessionRsp) CanDecode() gopacket.LayerClass

func (*OpenSessionRsp) DecodeFromBytes

func (o *OpenSessionRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*OpenSessionRsp) LayerType

func (*OpenSessionRsp) LayerType() gopacket.LayerType

func (*OpenSessionRsp) NextLayerType

func (*OpenSessionRsp) NextLayerType() gopacket.LayerType

type Operation

type Operation struct {

	// Function is the network function code of the message. The command field
	// indicates the specific functionality desired within this function class.
	Function NetworkFunction

	// Body is the defining body code. It is only relevant if the function is
	// Group, and is ignored otherwise.
	Body BodyCode

	// Enterprise is the enterprise number when the function is OEM/Group. It is
	// ignored otherwise.
	Enterprise iana.Enterprise

	// Command is the BMC function being requested, or the response.
	Command CommandNumber
}

Operation uniquely identifies a command that the BMC can perform. This is not terminology defined in the specification; this exists to allow us to identify the payload type of a particular IPMI message, which contains this type.

func (Operation) NextLayerType

func (o Operation) NextLayerType() gopacket.LayerType

func (Operation) String

func (o Operation) String() string

type OutputType

type OutputType uint8

OutputType represents an Event/Reading Type Code, specified in Table 36-2 and 42-2 of IPMI v1.5 and v2.0 respectively. Appeal: if you write a specification, please do not put slashes in names. Event/Reading Type Codes indicate the type of reading a sensor provides. It is mainly useful for discrete sensors (analogue sensors are threshold-based).

const (

	// OutputTypeThreshold indicates an analogue sensor whose values are
	// bucketed into states (e.g. Lower Non-critical, Upper Non-recoverable)
	// that are used in events it generates.
	OutputTypeThreshold OutputType
)

func (OutputType) Description

func (o OutputType) Description() string

func (OutputType) String

func (o OutputType) String() string

type Payload

type Payload interface {

	// Descriptor returns the PayloadDescriptor for the request layer. This
	// should avoid allocation, returning a pointer to static memory.
	// Technically this should be a member of the Request(), however we put it
	// here for consistency with Command. Note that unlike in Command, Request()
	// and Response() here cannot return nil.
	Descriptor() *PayloadDescriptor

	// Request returns the request layer that we send to the managed system,
	// immediately after the null V2Session layer. This should not allocate any
	// additional memory, and must not return nil.
	Request() gopacket.SerializableLayer

	// Response returns the response layer that we expect back from the managed
	// system following our request. This should not allocate any additional
	// memory, and must not return nil.
	Response() gopacket.DecodingLayer
}

Payload is implemented by outgoing IPMI v2.0 RMCP+ session setup interactions. Implementations have a -Payload suffix.

Note that although "IPMI Message" is payload, those interactions do not use this interface, as there is an additional Message layer that cannot be handled neatly and efficiently. This interface is for layers that are sent and received directly below the V2Session layer, outside of a session.

It is convention for structs implementing this interface to have Req and Rsp value fields for the Request() and Response() respectively.

type PayloadDescriptor

type PayloadDescriptor struct {

	// PayloadType identifies the payload, e.g. an IPMI or RAKP message. When
	// this has a value of OEM (0x2), it must be used together with the
	// Enterprise and PayloadID fields to identify the format.
	PayloadType PayloadType

	// Enterprise is the IANA Enterprise Number of the OEM who describes the
	// payload. This field only exists on the wire if the payload type is OEM
	// explicit.
	Enterprise iana.Enterprise

	// PayloadID identifies the payload within the Enterprise when the payload
	// is OEM-defined. This field only exists on the wire if the payload type is
	// OEM explicit.
	PayloadID uint16
}

PayloadDescriptor contains RMCP+ session fields which, taken together, describe the format of a IPMI v2.0 session payload. V2Session embeds this type. This type does not appear in the specification.

func (PayloadDescriptor) NextLayerType

func (p PayloadDescriptor) NextLayerType() gopacket.LayerType

func (PayloadDescriptor) String

func (p PayloadDescriptor) String() string

type PayloadType

type PayloadType uint8

PayloadType identifies the layer immediately within the RMCP+ session wrapper. Values are specified in 13.27.3 of the IPMI v2.0 spec. This is a 6-bit uint on the wire.

const (
	PayloadTypeIPMI PayloadType = 0x0

	// PayloadTypeOEM means "check the OEM IANA and OEM payload ID to find out
	// what this actually is".
	PayloadTypeOEM PayloadType = 0x2

	PayloadTypeOpenSessionReq PayloadType = 0x10
	PayloadTypeOpenSessionRsp PayloadType = 0x11
	PayloadTypeRAKPMessage1   PayloadType = 0x12
	PayloadTypeRAKPMessage2   PayloadType = 0x13
	PayloadTypeRAKPMessage3   PayloadType = 0x14
	PayloadTypeRAKPMessage4   PayloadType = 0x15
)

func (PayloadType) Description

func (p PayloadType) Description() string

func (PayloadType) String

func (p PayloadType) String() string

type PowerRestorePolicy

type PowerRestorePolicy uint8

PowerRestorePolicy indicates what the chassis is configured to do when mains power returns. This is a 2-bit uint on the wire.

const (
	// PowerRestorePolicyRemainOff means the system will not attempt to turn on
	// when power returns, regardless of state before the outage.
	PowerRestorePolicyRemainOff PowerRestorePolicy = iota

	// PowerRestorePolicyPriorState means the system will return to the state it
	// was in when the power was lost.
	PowerRestorePolicyPriorState

	// PowerRestorePolicyPowerOn means the system will always attempt to turn on
	// when power returns, regardless of state before the outage.
	PowerRestorePolicyPowerOn

	// PowerRestorePolicyUnknown means the BMC does not know what the chassis
	// will do.
	PowerRestorePolicyUnknown
)

func (PowerRestorePolicy) Description

func (p PowerRestorePolicy) Description() string

Description returns a human-readable representation of the policy.

func (PowerRestorePolicy) String

func (p PowerRestorePolicy) String() string

type PrivilegeLevel

type PrivilegeLevel uint8

PrivilegeLevel dictates which IPMI commands a given user can execute over a given channel. Levels are defined in section 6.8 of the IPMI v2.0 spec. On the wire, the privilege level is a 4-bit uint.

Each channel and user has an individual privilege level limit, which constrains the operations that can be performed via that channel or by that user respectively. The lower of the two is the effective limit.

Sessions start at the User privilege level, but can be changed with the Set Session Privilege Level command.

const (
	// PrivilegeLevelHighest is used in the RMCP+ Open Session Request message
	// to ask the BMC to set the session maximum privilege level to the highest
	// it is willing to, given the cipher suites the remote console indicated
	// support for. Note this is for the channel; the user (provided in RAKP1)
	// may have a lower privilege level limit.
	//
	// Use of this value is not recommended for two reasons. Firstly, you
	// normally know what privilege level you require in advance, and this may
	// result in insufficient privileges, or overly lax ones (breaking the
	// principle of least privilege). Secondly, it is not supported by all BMCs,
	// e.g. Super Micro.
	//
	// This is a reserved value in IPMI v1.5.
	PrivilegeLevelHighest PrivilegeLevel = iota

	PrivilegeLevelCallback
	PrivilegeLevelUser
	PrivilegeLevelOperator
	PrivilegeLevelAdministrator
	PrivilegeLevelOEM
)

func (PrivilegeLevel) String

func (p PrivilegeLevel) String() string

type RAKPMessage1

type RAKPMessage1 struct {
	layers.BaseLayer

	// Tag is an arbitrary 8-bit quantity used by the remote console to match
	// this message with RAKP Message 2.
	Tag uint8

	// ManagedSystemSessionID is the session ID returned by the BMC in the RMCP+
	// Open Session Response message.
	ManagedSystemSessionID uint32

	// RemoteConsoleRandom is a 16-byte random value selected by the remote
	// console. Although it is referred to as a number, its byte order is not
	// reversed on the wire.
	RemoteConsoleRandom [16]byte

	// PrivilegeLevelLookup indicates whether to use both the MaxPrivilegeLevel
	// and Username to search for the relevant user entry. If this is true and
	// the username is empty, we effectively use role-based authentication. If
	// this is false, the supplied MaxPrivilegeLevel will be ignored when
	// searching for the Username.
	PrivilegeLevelLookup bool

	// MaxPrivilegeLevel is the upper privilege limit for the session. If
	// PrivilegeLevelLookup is true, it is also used in the user entry lookup.
	// Regardless of this value, if PrivilegeLevelLookup is false, the channel
	// or user privilege level limit may further constrain allowed commands.
	MaxPrivilegeLevel PrivilegeLevel

	// Username is the name of the user to search for in user entries. Only
	// ASCII characters allowed (excluding \0), maximum length 16.
	Username string
}

RAKPMessage1 represents a RAKP Message 1, defined in 13.20 of the spec. It begins the session authentication process.

func (*RAKPMessage1) DecodeFromBytes

func (r *RAKPMessage1) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*RAKPMessage1) LayerType

func (*RAKPMessage1) LayerType() gopacket.LayerType

func (*RAKPMessage1) NextLayerType

func (*RAKPMessage1) NextLayerType() gopacket.LayerType

func (*RAKPMessage1) SerializeTo

type RAKPMessage1Payload

type RAKPMessage1Payload struct {
	Req RAKPMessage1
	Rsp RAKPMessage2
}

func (*RAKPMessage1Payload) Descriptor

func (*RAKPMessage1Payload) Descriptor() *PayloadDescriptor

Descriptor returns PayloadDescriptorRAKPMessage1.

func (*RAKPMessage1Payload) Request

func (*RAKPMessage1Payload) Response

type RAKPMessage2

type RAKPMessage2 struct {
	layers.BaseLayer

	// Tag is equal to the tag sent by the remote console in RAKP Message 1.
	Tag uint8

	// Status indicates whether the remote console's RAKP Message 1 was
	// accepted, and if not, why not.
	Status StatusCode

	// RemoteConsoleSessionID can be used by the remote console along with the
	// tag to determine which session this response pertains to.
	RemoteConsoleSessionID uint32

	// ManagedSystemRandom is a random 16-byte value selected by the managed
	// system. Although it is referred to as a number in the spec, its byte
	// order is not reversed on the wire.
	ManagedSystemRandom [16]byte

	// ManagedSystemGUID is typically specified by the BMC's SMBIOS
	// implementation. It is opaque for our purposes. The spec suggests the
	// remote console is meant to validate this is as expected, however this
	// requires an inventory. A test Supermicro X10 BMC returns all 0s for this
	// field.
	ManagedSystemGUID [16]byte

	// AuthCode is an integrity check value over this message. Its size depends
	// on the algorithm; if we are using None, it will be empty. If we are using
	// MD5-128, it is not a signature.
	AuthCode []byte
}

RAKPMessage2 is sent by the managed system in response to a RAKP Message 1, and is defined in section 13.21.

func (*RAKPMessage2) CanDecode

func (r *RAKPMessage2) CanDecode() gopacket.LayerClass

func (*RAKPMessage2) DecodeFromBytes

func (r *RAKPMessage2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*RAKPMessage2) LayerType

func (*RAKPMessage2) LayerType() gopacket.LayerType

func (*RAKPMessage2) NextLayerType

func (*RAKPMessage2) NextLayerType() gopacket.LayerType

type RAKPMessage3

type RAKPMessage3 struct {
	layers.BaseLayer

	// Tag is an arbitrary 8-bit quantity used by the remote console to match
	// this message with RAKP Message 4.
	Tag uint8

	// Status indicates whether the managed system's RAKP Message 2 was
	// accepted. If it was not, the BMC will remove the session state, and the
	// remote console will have to start again from RAKP Message 1.
	Status StatusCode

	// ManagedSystemSessionID is the session ID returned by the BMC in the RMCP+
	// Open Session Response message.
	ManagedSystemSessionID uint32

	// AuthCode is an integrity check value over this message. Its size depends
	// on the algorithm; if we are using None, it will be empty.
	AuthCode []byte
}

RAKPMessage3 is sent by the remote console in response to a RAKP Message 2, and is defined in section 13.22.

func (*RAKPMessage3) LayerType

func (*RAKPMessage3) LayerType() gopacket.LayerType

func (*RAKPMessage3) SerializeTo

type RAKPMessage3Payload

type RAKPMessage3Payload struct {
	Req RAKPMessage3
	Rsp RAKPMessage4
}

func (*RAKPMessage3Payload) Descriptor

func (*RAKPMessage3Payload) Descriptor() *PayloadDescriptor

Descriptor returns PayloadDescriptorRAKPMessage3.

func (*RAKPMessage3Payload) Request

func (*RAKPMessage3Payload) Response

type RAKPMessage4

type RAKPMessage4 struct {
	layers.BaseLayer

	// Tag is equal to the tag sent by the remote console in RAKP Message 3.
	Tag uint8

	// Status indicates whether the remote console's RAKP Message 3 was
	// accepted, and if not, why not.
	Status StatusCode

	// RemoteConsoleSessionID can be used by the remote console along with the
	// tag to determine which session this response pertains to.
	RemoteConsoleSessionID uint32

	// ICV is an integrity check value over this message. Its size depends
	// on the algorithm; if we are using None, it will be empty. If we are using
	// MD5-128, it is not a signature.
	ICV []byte
}

RAKPMessage4 is sent by the managed system in response to a RAKP Message 3, and is defined in section 13.23.

func (*RAKPMessage4) CanDecode

func (r *RAKPMessage4) CanDecode() gopacket.LayerClass

func (*RAKPMessage4) DecodeFromBytes

func (r *RAKPMessage4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*RAKPMessage4) LayerType

func (*RAKPMessage4) LayerType() gopacket.LayerType

func (*RAKPMessage4) NextLayerType

func (*RAKPMessage4) NextLayerType() gopacket.LayerType

type RateUnit

type RateUnit uint8

RateUnit represents the duration over which a basic unit is given. It lets us distinguish between n times per millisecond and n times per day, among other values. Rate units are specified in byte 21 of the Full Sensor Record table in 37.1 and 43.1 of v1.5 and v2.0 respectively. This is a 3-bit uint on the wire.

const (
	RateUnitNone RateUnit = iota
	RateUnitPerMicrosecond
	RateUnitPerMillisecond
	RateUnitPerSecond
	RateUnitPerMinute
	RateUnitPerHour
	RateUnitPerDay
)

func (RateUnit) Duration

func (r RateUnit) Duration() time.Duration

Duration returns the underlying "per" period within the rate unit. Returns 0 if called on an unrecognised rate unit.

func (RateUnit) String

func (r RateUnit) String() string

type RecordID

type RecordID uint16

RecordID uniquely identifies an SDR in the SDR Repository, and is used for access. Record IDs are not guaranteed to be enumerated sequentially, let alone consecutively, and there are likely to be gaps in them once the entire repository has been retrieved. It is more accurate in terms of the specification's guarantees to think of them as opaque keys into the SDR "map", rather than sparse array indices. The only requirement is that, at a given point in time (which is vague as IPMI does not have transactions), each SDR in the repo has a unique Record ID.

A given Record ID is only valid until the SDR Repository is written to (either addition or removal of an SDR), at which point the controller may re-assign the ID to another SDR, or remove it entirely, giving the original SDR a new ID, possible in turn re-assigned from another SDR. This can be detected using the timestamps returned in "Get SDR Repository Info", however there is an inherent race condition here (the command does not support reservations), so instead we check the record key matches the one expected at retrieval time. See 33.8 in IPMI v2.0 for more detail. Note this is not the same as a sensor ID, which is a field within a sensor SDR (yes, sensor SDR - there are non-sensor SDRs e.g. Device Locator Records!).

const (
	// RecordIDFirst always points to the "first" SDR in the repository. It is
	// used to kick off retrieval of SDRs by iterating through them.
	RecordIDFirst RecordID = 0x0000

	// RecordIDLast always points to the "last" SDR in this repository. The
	// "next" SDR will also be RecordIDLast. When this ID is seen, the record
	// should be read, then iteration stopped as the end has been reached.
	RecordIDLast RecordID = 0xffff
)

type RecordType

type RecordType uint8

RecordType indicates the format of a Sensor Data Record, e.g. a Full Sensor Record, Compact Sensor Record, or Entity Association Record. It is a field in the SDR header, essential for informing the remote console how to interpret the rest of the packet. Although "sensor" is in the name, an SDR does not necessarily pertain to a sensor.

const (
	RecordTypeFullSensor                        RecordType = 0x01
	RecordTypeCompactSensor                     RecordType = 0x02
	RecordTypeEventOnly                         RecordType = 0x03
	RecordTypeEntityAssociation                 RecordType = 0x08
	RecordTypeDeviceRelativeEntityAssociation   RecordType = 0x09
	RecordTypeGenericDeviceLocator              RecordType = 0x10
	RecordTypeFRUDeviceLocator                  RecordType = 0x11
	RecordTypeManagementControllerDeviceLocator RecordType = 0x12
	RecordTypeManagementControllerConfirmation  RecordType = 0x13
	RecordTypeBMCMessageChannelInfo             RecordType = 0x14
)

func (RecordType) Description

func (t RecordType) Description() string

func (RecordType) NextLayerType

func (t RecordType) NextLayerType() gopacket.LayerType

func (RecordType) String

func (t RecordType) String() string

type ReservationID

type ReservationID uint16

ReservationID is a token returned by the BMC in response to the Reserve SDR Repository command, that is invalidated when SDR Record IDs may have changed. Reservations exist to solve the race problem where a record is identified for deletion or modification, but before it can be, the SDR is updated such that the Record ID changes, and the wrong SDR is updated. In addition to write operations, a reservation is required when reading from a non-0 offset of an SDR. Partial reads may be required even if the entire SDR is desired, when the SDR does not fit in the BMC's packet buffer.

Note the SDR Repository device is allowed to not cancel the reservation if it knows a modification has not affected any existing Record IDs (33.11.2), so this cannot be used as a guarantee that the repository has not been changed or as a mechanism to watch for changes. It only guarantees consistency since the reservation was obtained. You need to occasionally check the timestamps returned by Get SDR Repository Info.

Reserving the SDR repo effectively stamps it with an owner. The next application that attempts to reserve it will simply overwrite that value - there is no guarantee of access. Back-off, ideally with jitter, is essential to reservation logic, to ensure one of two competing applications will eventually be able to finish its work and they don't repeatedly stall each other. Unfortunately this relies on other applications doing the right thing.

type ReserveSDRRepositoryCmd

type ReserveSDRRepositoryCmd struct {
	Rsp ReserveSDRRepositoryRsp
}

func (*ReserveSDRRepositoryCmd) Name

Name returns "Reserve SDR Repository".

func (*ReserveSDRRepositoryCmd) Operation

func (*ReserveSDRRepositoryCmd) Operation() *Operation

Operation returns &OperationReserveSDRRepositoryReq.

func (*ReserveSDRRepositoryCmd) RemoteLUN

func (c *ReserveSDRRepositoryCmd) RemoteLUN() LUN

func (*ReserveSDRRepositoryCmd) Request

func (*ReserveSDRRepositoryCmd) Response

type ReserveSDRRepositoryRsp

type ReserveSDRRepositoryRsp struct {
	layers.BaseLayer

	ReservationID ReservationID
}

ReserveSDRRepositoryRsp represents the response to a Reserve SDR Repository command, specified in 33.11 of IPMI v2.0.

func (*ReserveSDRRepositoryRsp) CanDecode

func (*ReserveSDRRepositoryRsp) DecodeFromBytes

func (r *ReserveSDRRepositoryRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*ReserveSDRRepositoryRsp) LayerType

func (*ReserveSDRRepositoryRsp) NextLayerType

func (*ReserveSDRRepositoryRsp) NextLayerType() gopacket.LayerType

type SDR

type SDR struct {
	layers.BaseLayer

	// ID is the current Record ID for the SDR. This is not the record key (that
	// is a set of fields specific to the record type), and may change if the
	// SDR Repository is modified. See RecordID documentation for more details.
	ID RecordID

	// Version is the version number of the SDR specification. It is used with
	// the Type field to control how the record is parsed. We return an error
	// during decoding if this is not supported.
	Version uint8

	// Type indicates what the SDR describes. Confusingly, not all SDRs pertain
	// to sensors.
	Type RecordType

	// Length is the number of remaining bytes in the payload (i.e. after the header).
	//
	// This means the max SDR size on the wire is 260 bytes. In practice, OEM
	// records notwithstanding, it is unlikely to be >60.
	//
	// If it weren't for this field, the limit for the whole SDR including
	// header could theoretically be 255 + the max supported payload size (the
	// SDR Repo Device commands provide no way to address subsequent sections
	// for reading).
	Length uint8
}

SDR represents a Sensor Data Record header, outlined at the beginning of 37 and 43 of IPMI v1.5 and 2.0 respectively. These fields are common to all SDRs, and is the limit of what the SDR Repository Device cares about: the record key and body are opaque bytes.

Despite the name, an SDR may not pertain to a sensor, e.g. there are Device Locator and Entity Association SDR types.

func (*SDR) CanDecode

func (s *SDR) CanDecode() gopacket.LayerClass

func (*SDR) DecodeFromBytes

func (s *SDR) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*SDR) LayerType

func (*SDR) LayerType() gopacket.LayerType

func (*SDR) NextLayerType

func (s *SDR) NextLayerType() gopacket.LayerType

type SensorDirection

type SensorDirection uint8

SensorDirection indicates whether a sensor is monitoring an input or output relative to the entity, e.g. input voltage vs. output voltage. It is specified in byte 29 of the Full Sensor Record Table 43-1 in IPMI v2.0.

const (
	SensorDirectionUnspecified SensorDirection = iota
	SensorDirectionInput
	SensorDirectionOutput
)

func (SensorDirection) Description

func (s SensorDirection) Description() string

func (SensorDirection) String

func (s SensorDirection) String() string

type SensorRecordKey

type SensorRecordKey struct {

	// OwnerAddress uniquely identifies a management controller on the IPMB.
	// This is relevant for device-relative entity instances.
	OwnerAddress Address
	Channel      Channel
	OwnerLUN     LUN

	// Number uniquely identifies the sensor within the context of a given
	// owner. 0xff is used to indicate no more sensors, so there are 255 useful
	// values.
	Number uint8
}

SensorRecordKey contains the Record Key fields for the Full Sensor Record and Compact Sensor Record SDR types.

type SensorType

type SensorType uint8

SensorType indicates what a sensor measures, e.g. a temperature, chassis intrusion, or cooling device. There are some seemingly conflicting values, e.g. temperature (0x01) could be that of a processor (0x07), however the types after 0x04 are seemingly for discrete sensors, and have an additional sub-type in the form of a sensor specific offset. See Table 36-3 and 42-3 in v1.5 and v2.0 respectively.

const (
	SensorTypeTemperature SensorType
	SensorTypeVoltage
	SensorTypeCurrent
	SensorTypeFan
	SensorTypePhysicalSecurity
	SensorTypePlatformSecurity
	SensorTypeProcessor
	SensorTypePowerSupply
	SensorTypePowerUnit
	SensorTypeCoolingDevice
	SensorTypeOtherUnitsBasedSensor
	SensorTypeMemory
	SensorTypeDriveBay
)

func (SensorType) Description

func (t SensorType) Description() string

func (SensorType) String

func (t SensorType) String() string

type SensorUnit

type SensorUnit uint8

SensorUnit defines the unit of a sensor. It is specified in 37.17 and 43.17 of v1.5 and v2.0 respectively. It is an 8-bit uint on the wire.

const (
	SensorUnitCelsius SensorUnit
	SensorUnitFahrenheit
	SensorUnitKelvin
	SensorUnitVolts
	SensorUnitAmps
	SensorUnitWatts
	SensorUnitJoules
	SensorUnitCoulombs
	SensorUnitVoltamperes
	SensorUnitNits
	SensorUnitLumen
	SensorUnitLux
	SensorUnitCandela
	SensorUnitKilopascals
	SensorUnitPoundsPerSquareInch
	SensorUnitNewtons
	SensorUnitCubicFeetPerMinute
	SensorUnitRotationsPerMinute
	SensorUnitHertz
	SensorUnitMicroseconds
	SensorUnitMilliseconds
	SensorUnitSeconds
	SensorUnitMinutes
	SensorUnitHours
	SensorUnitDays
	SensorUnitWeeks
	SensorUnitMils
	SensorUnitInches
	SensorUnitFeet
	SensorUnitCubicInches
	SensorUnitCubicFeet
	SensorUnitMillimeters
	SensorUnitCentimeters
	SensorUnitMeters
	SensorUnitCubicCentimeters
	SensorUnitCubicMeters
	SensorUnitLiters
	SensorUnitFluidOunces
	SensorUnitRadians
	SensorUnitSteradians
	SensorUnitRevolutions
	SensorUnitCycles
	SensorUnitGravities
	SensorUnitOunces
	SensorUnitPounds
	SensorUnitFeetPounds
	SensorUnitOunceInches
	SensorUnitGauss
	SensorUnitGilberts
	SensorUnitHenry
	SensorUnitMillihenry
	SensorUnitFarad
	SensorUnitMicrofarad
	SensorUnitOhms
	SensorUnitSiemens
	SensorUnitMoles
	SensorUnitBecquerel
	SensorUnitPartsPerMillion

	SensorUnitDecibels
	SensorUnitDecibelsAFilter
	SensorUnitDecibelsCFilter
	SensorUnitGray
	SensorUnitSieverts
	SensorUnitColorTempKelvin
	SensorUnitBits
	SensorUnitKilobits
	SensorUnitMegabits
	SensorUnitGigabits
	SensorUnitBytes
	SensorUnitKilobytes
	SensorUnitMegabytes
	SensorUnitGigabytes
	SensorUnitWords
	SensorUnitDwords
	SensorUnitQwords
	SensorUnitMemoryLines
	SensorUnitHits
	SensorUnitMisses
	SensorUnitRetries
	SensorUnitResets
	SensorUnitOverflows
	SensorUnitUnderruns
	SensorUnitCollisions
	SensorUnitPackets
	SensorUnitMessages
	SensorUnitCharacters
	SensorUnitErrors
	SensorUnitCorrectableErrors
	SensorUnitUncorrectableErrors
	SensorUnitFatal
	SensorUnitGrams
)

func (SensorUnit) String

func (s SensorUnit) String() string

func (SensorUnit) Symbol

func (s SensorUnit) Symbol() string

type SessionHandle

type SessionHandle uint8

SessionHandle uniquely identifies an active session within the context of a given channel, as opposed to globally for the BMC which is the case for SessionID. Each new session receives an incremented handle number. 0x00 is ostensibly reserved, or used for single-session channels, however some vendors use it as a valid handle number.

type SessionIndex

type SessionIndex uint8

SessionIndex represents the first field of the Get Session Info request, defined in table 18-20 and 22-25 of IPMI v1.5 and v2.0 respectively. Although it is only used in this command, it has its own time as there are several sentinel values.

const (
	// SessionIndexCurrent is a sentinel value for the Index field in a Get
	// Session Info request, requesting information about the session the
	// command was received over.
	SessionIndexCurrent SessionIndex = 0x00

	// SessionIndexHandle is a sentinel value for the Index field in a Get
	// Session Info request, requesting information about the specified session
	// handle rather than index. See type SessionHandle for its definition.
	SessionIndexHandle SessionIndex = 0xfe

	// SessionIndexID is a sentinel value for the Index field in a Get Session
	// Info request, requesting information about the specified session ID
	// rather than index.
	SessionIndexID SessionIndex = 0xff
)

type SessionSelector

type SessionSelector struct {
	layers.BaseLayer

	// IsRMCPPlus indicates whether the payload of this layer is an IPMI v2.0
	// session wrapper (true), or a v1.5 session wrapper (false).
	IsRMCPPlus bool
}

SessionSelector is a dummy layer that lives between the RMCP layer and the IPMI session wrapper. It allows us to choose the correct session wrapper layer based on the AuthType field, which indicates whether the packet is using v1.5 or v2.0 sessions. Gopacket's RMCP layer allows registering a single layer for the IPMI message class, which isn't flexible enough for what we really need. Hence the existence of this layer, which is 0-length. Ideally this logic would go in gopacket, however we have not contributed those types back to the library as they are a little too specific.

func (*SessionSelector) CanDecode

func (s *SessionSelector) CanDecode() gopacket.LayerClass

func (*SessionSelector) DecodeFromBytes

func (s *SessionSelector) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*SessionSelector) LayerType

func (*SessionSelector) LayerType() gopacket.LayerType

func (*SessionSelector) NextLayerType

func (s *SessionSelector) NextLayerType() gopacket.LayerType

type SetSessionPrivilegeLevelCmd

type SetSessionPrivilegeLevelCmd struct {
	Req SetSessionPrivilegeLevelReq
	Rsp SetSessionPrivilegeLevelRsp
}

func (*SetSessionPrivilegeLevelCmd) Name

Name returns "Set Session Privilege Level".

func (*SetSessionPrivilegeLevelCmd) Operation

func (*SetSessionPrivilegeLevelCmd) Operation() *Operation

Operation returns OperationSetSessionPrivilegeLevelReq.

func (*SetSessionPrivilegeLevelCmd) RemoteLUN

func (c *SetSessionPrivilegeLevelCmd) RemoteLUN() LUN

func (*SetSessionPrivilegeLevelCmd) Request

func (*SetSessionPrivilegeLevelCmd) Response

type SetSessionPrivilegeLevelReq

type SetSessionPrivilegeLevelReq struct {
	layers.BaseLayer

	// PrivilegeLevel indicates the privilege level to switch to.
	// Omitting this field will retrieve the current privilege level without modification.
	// PrivilegeLevelHighest and PrivilegeLevelCallback are invalid values.
	PrivilegeLevel PrivilegeLevel
}

SetSessionPrivilegeLevelReq implements the Set Session Privilege Level command, specified in section 18.16 of v1.5 and 22.18 of v2.0.

func (*SetSessionPrivilegeLevelReq) LayerType

func (*SetSessionPrivilegeLevelReq) SerializeTo

type SetSessionPrivilegeLevelRsp

type SetSessionPrivilegeLevelRsp struct {
	layers.BaseLayer

	// PrivilegeLevel indicates the new (possibly updated) privilege level
	// of the user in the active session.
	PrivilegeLevel PrivilegeLevel
}

func (*SetSessionPrivilegeLevelRsp) CanDecode

func (*SetSessionPrivilegeLevelRsp) DecodeFromBytes

func (r *SetSessionPrivilegeLevelRsp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*SetSessionPrivilegeLevelRsp) LayerType

func (*SetSessionPrivilegeLevelRsp) NextLayerType

type SlaveAddress

type SlaveAddress uint8

SlaveAddress is a 7-bit I2C slave address. The requester and responder of IPMB messages is always a slave address; in LAN messages, the addresses can also be software IDs.

const (
	// SlaveAddressBMC is the address of the BMC. Accounting for the 0 slave
	// address bit, this is equivalent to an address of 0x20.
	SlaveAddressBMC SlaveAddress = 0x10
)

func (SlaveAddress) Address

func (s SlaveAddress) Address() Address

Address converts a slave address into a value suitable for inclusion in an IPMI message.

func (SlaveAddress) String

func (s SlaveAddress) String() string

type SoftwareID

type SoftwareID uint8

SoftwareID represents a piece of system software or IPMI event message generator. This is a 7-bit uint field.

const (
	// SoftwareIDRemoteConsole1 is the software ID of the first remote console.
	// There are 7 in total.
	SoftwareIDRemoteConsole1 SoftwareID = 0x40
)

func (SoftwareID) Address

func (s SoftwareID) Address() Address

Address converts a software ID into an address value suitable for inclusion in an IPMI message.

func (SoftwareID) String

func (s SoftwareID) String() string

type StatusCode

type StatusCode uint8

StatusCode represents an RMCP+ status code. A value of this type is contained in the RMCP+ Open Session Response and RAKP Messages 2, 3 and 4. This is the equivalent of an IPMI completion code. See section 13.24 for the full list of definitions.

const (
	// StatusCodeOK indicates successful completion, absent of error. This can
	// exist in all message types.
	StatusCodeOK StatusCode = iota

	// StatusCodeInsufficientResources indicates there were insufficient
	// resources to create a session. This can exist in all message types.
	StatusCodeInsufficientResources

	// StatusCodeInvalidSessionID indicates the managed system or remote console
	// does not recognise the session ID sent by the other end. In practice, the
	// remote console will likely be at fault. This can exist in all message
	// types.
	StatusCodeInvalidSessionID

	// StatusCodeUnauthorisedName is sent in RAKP Message 2 to indicate the
	// username was not found in the BMC's users table.
	StatusCodeUnauthorisedName StatusCode = 0x0d

	// StatusCodeUnsupportedCipherSuite is sent in RMCP+ Open Session Response
	// to indicate the BMC cannot satisfy an acceptable combination of the
	// requested authentication/integrity/encryption parameters.
	StatusCodeUnsupportedCipherSuite StatusCode = 0x11

	// StatusCodeInvalidRequestLength is sent when the request is too short, or
	// too long. This is an IPMI rather than RMCP+ value, however some BMCs
	// return it regardless. It resides in the reserved status code space,
	// which we assume will never be used.
	StatusCodeInvalidRequestLength StatusCode = 0xc7
)

func (StatusCode) Description

func (s StatusCode) Description() string

func (StatusCode) IsTemporary

func (s StatusCode) IsTemporary() bool

IsTemporary returns whether the code indicates a retry may produce a successful result, or the error is permanent.

func (StatusCode) String

func (s StatusCode) String() string

type StringDecoder

type StringDecoder interface {

	// Decode parses the first c characters (0 <= c <= 30) in b in the expected
	// format (N.B. this could be a varying number of bytes depending on the
	// encoding), returning the resulting string and number of bytes consumed,
	// or an error if the data is too short or invalid.
	//
	// c was implemented as an int rather than uint8 to reduce the number of
	// conversions required.
	Decode(b []byte, c int) (string, int, error)
}

StringDecoder is implemented by things that know how to parse the final ID String field of full and compact SDRs.

type StringDecoderFunc

type StringDecoderFunc func([]byte, int) (string, int, error)

StringDecoderFunc eases implementation of stateless StringDecoders.

func (StringDecoderFunc) Decode

func (f StringDecoderFunc) Decode(b []byte, c int) (string, int, error)

Decode calls the contained function on the inputs, passing through the returned values verbatim.

type StringEncoding

type StringEncoding uint8

StringEncoding describes the most significant two bits of the SDR Type/Length Byte, specified in 37.15 and 43.15 of v1.5 and v2.0 respectively.

const (
	// StringEncodingUnicode, contrary to the name, typically suggests an
	// unspecified encoding. IPMItool displays a hex representation of the
	// underlying bytes, while OpenIPMI interprets it identically to
	// StringEncoding8BitAsciiLatin1. Given Unicode is only a character set and
	// the spec does not suggest any encoding, there is no right answer. The
	// resulting variety of implementations means use of this value by a BMC
	// should be regarded as a bug.
	StringEncodingUnicode StringEncoding = iota
	StringEncodingBCDPlus
	StringEncodingPacked6BitAscii
	StringEncoding8BitAsciiLatin1
)

func (StringEncoding) Decoder

func (e StringEncoding) Decoder() (StringDecoder, error)

func (StringEncoding) Description

func (e StringEncoding) Description() string

func (StringEncoding) String

func (e StringEncoding) String() string

type V1Session

type V1Session struct {
	layers.BaseLayer

	// AuthType indicates the algorithm protecting the inner message, whose
	// signature is contained in the AuthCode field. If this is
	// AuthenticationTypeNone, the AuthCode field will be skipped when
	// serialising. As this struct is for IPMI v1.x only,
	// AuthenticationTypeRMCPPlus is an invalid value.
	AuthType AuthenticationType

	// Sequence is the session sequence number, intended to protect against
	// replay attacks. A given session has inbound and outbound sequence
	// numbers, so the one this corresponds to will depend on whether we're
	// sending or receiving a packet. Each end selects the starting sequence
	// number for the messages they receive. The sequence number increments for
	// retransmits.
	//
	// Note this is not used for matching responses with requests; that is done
	// one level further down, with the IPMI message sequence field.
	Sequence uint32

	// ID is the session ID, chosen by the BMC and sent in the Activate Session
	// response. This will be a temporary ID during session initialisation.
	ID uint32

	// AuthCode is a signature whose format depends on the AuthType. This field
	// is absent from the wire format if AuthType == AuthTypeNone. Whether this
	// is present or not when the Authentication Type = OEM is dependent on the
	// OEM identified in the Get Channel Authentication Capabilities command.
	AuthCode [16]byte

	// Length is the length of the contained IPMI message.
	Length uint8

	// AuthenticationAlgorithm is called to generate a checksum of the packet.
	AuthenticationAlgorithm hash.Hash
}

V1Session represents the IPMI v1.5 session header. It wraps all IPMI commands. The zero value is suitable for commands sent "outside" of a session, e.g. Get Channel Authentication Capabilities, and Get Device GUID. See 6.11.7 for more details.

func (*V1Session) CanDecode

func (s *V1Session) CanDecode() gopacket.LayerClass

func (*V1Session) DecodeFromBytes

func (s *V1Session) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*V1Session) LayerType

func (*V1Session) LayerType() gopacket.LayerType

func (*V1Session) NextLayerType

func (s *V1Session) NextLayerType() gopacket.LayerType

func (*V1Session) SerializeTo

type V2Session

type V2Session struct {
	layers.BaseLayer
	PayloadDescriptor

	// Encrypted is true if the payload is encrypted, false if it is not.
	Encrypted bool

	// Authenticated is true if the payload is signed, false if it is not. Iff
	// this is false, the Pad and Authentication fields are absent from the wire
	// format.
	Authenticated bool

	// ID is the session ID, null for messages outside of a session. For
	// received packets, this is our session ID. For sent packets, this is the
	// other end's session ID. Note that these two numbers are separate, and
	// exchanged in the Open Session Request/Response messages.
	ID uint32

	// Sequence is the session sequence number, incremented regardless of
	// whether the packet is a retry. The sequence number is intended to be used
	// for rejecting replayed packets. Note RMCP+ sessions use a pair of
	// sequence numbers for authenticated packets, and another independent pair
	// for unauthenticated packets (4 in total). An endpoint verifies the
	// sequence number is expected before checking integrity (6.12.13), then
	// verifies integrity, then accepts the sequence number.
	Sequence uint32

	// Length is the size of the payload in bytes. This will never be 0.
	Length uint16

	// Pad is the number of 0xff bytes added after the payload data to make the
	// range over which the authentication data is created a multiple of 4
	// bytes. Valid values are therefore 0 through 3.
	Pad uint8

	// Signature is the authentication data calculated according to the
	// integrity algorithm negotiated during session establishment.
	Signature []byte

	// IntegrityAlgorithm is an instance of the integrity algorithm negotiated
	// during session establishment. If this is an HMAC, it is already loaded
	// with the appropriate key. If this is nil, serialisation and
	// deserialisation of authenticated packets will fail.
	//
	// We assume all ICVs are calculated from the auth type field (0x6) to the
	// next header field (0x7) - which is the case for all algorithms in the
	// spec (13.28.4).
	IntegrityAlgorithm hash.Hash

	// ConfidentialityLayerType is the type of the layer that can decode
	// encrypted payloads. This value is returned when the payload is an IPMI
	// message and Encrypted is true. If this is nil, decoding of encrypted
	// packets will not work.
	ConfidentialityLayerType gopacket.LayerType
}

V2Session represents an IPMI v2.0/RMCP+ session header. Its format is specified in section 13.6 of the spec. N.B. the default instance of this struct can only deal with unauthenticated packets. The IntegrityAlgorithm attribute must be set to deal with all packets.

func (*V2Session) CanDecode

func (s *V2Session) CanDecode() gopacket.LayerClass

func (*V2Session) DecodeFromBytes

func (s *V2Session) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

func (*V2Session) LayerType

func (*V2Session) LayerType() gopacket.LayerType

func (*V2Session) NextLayerType

func (s *V2Session) NextLayerType() gopacket.LayerType

func (*V2Session) SerializeTo

Jump to

Keyboard shortcuts

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