Documentation
¶
Overview ¶
Package open provides in-band (System Interface) access to a local BMC.
- Linux: OpenIPMI character device (/dev/ipmiN) via ioctl
- Windows: Microsoft_IPMI WMI provider (ipmidrv.sys) via COM or PowerShell
Callers build a transport-neutral Request and send it through a Backend. Platform backends map Request onto their native plumbing and return the raw response as "completion code + payload".
Index ¶
- Constants
- Variables
- func IO(typ, nr uintptr) uintptr
- func IOC(dir, typ, nr, size uintptr) uintptr
- func IOCTL(fd, name, data uintptr) error
- func IOC_DIR(nr uintptr) uintptr
- func IOC_NR(nr uintptr) uintptr
- func IOC_SIZE(nr uintptr) uintptr
- func IOC_TYPE(nr uintptr) uintptr
- func IOR(typ, nr, size uintptr) uintptr
- func IOW(typ, nr, size uintptr) uintptr
- func IOWR(typ, nr, size uintptr) uintptr
- func OpenDevice(devnum int32) (*os.File, error)
- type Backend
- type DeviceBackend
- type IPMI_ADDR
- type IPMI_CHANNEL_LUN_ADDRESS_SET
- type IPMI_CMDSPEC
- type IPMI_CMDSPEC_CHANS
- type IPMI_IPMB_ADDR
- type IPMI_IPMB_DIRECT_ADDR
- type IPMI_LAN_ADDR
- type IPMI_MSG
- type IPMI_RECV
- type IPMI_REQ
- type IPMI_REQ_SETTIME
- type IPMI_SYSTEM_INTERFACE_ADDR
- type IPMI_TIMING_PARAMS
- type Request
Constants ¶
const ( BackendAuto = "auto" BackendCOM = "wmi-com" BackendPowerShell = "wmi-ps" )
Backend names accepted by ResolveBackend (and goipmi's --open-backend). They select which Microsoft_IPMI WMI transport Windows uses; Linux always uses DeviceBackend and ignores the preference.
const ( IOC_NRBITS = 8 IOC_TYPEBITS = 8 IOC_SIZEBITS = 14 IOC_DIRBITS = 2 IOC_NONE = 0x0 IOC_READ = 0x1 IOC_WRITE = 0x2 IOC_NRMASK = ((1 << IOC_NRBITS) - 1) IOC_TYPEMASK = ((1 << IOC_TYPEBITS) - 1) IOC_SIZEMASK = ((1 << IOC_SIZEBITS) - 1) IOC_DIRMASK = ((1 << IOC_DIRBITS) - 1) IOC_NRSHIFT = 0 IOC_TYPESHIFT = (IOC_NRSHIFT + IOC_NRBITS) IOC_SIZESHIFT = (IOC_TYPESHIFT + IOC_TYPEBITS) IOC_DIRSHIFT = (IOC_SIZESHIFT + IOC_SIZEBITS) IOC_IN = (IOC_WRITE << IOC_DIRSHIFT) IOC_OUT = (IOC_READ << IOC_DIRSHIFT) IOC_INOUT = ((IOC_WRITE | IOC_READ) << IOC_DIRSHIFT) IOCSIZE_MASK = (IOC_SIZEMASK << IOC_SIZESHIFT) IOCSIZE_SHIFT = (IOC_SIZESHIFT) )
cSpell:disable
const ( IPMI_BUF_SIZE = 1024 IPMI_MAX_ADDR_SIZE = 32 // Channel for talking directly with the BMC (system interface only). IPMI_BMC_CHANNEL = 0xf IPMI_NUM_CHANNELS = 0x10 IPMI_RESPONSE_RECV_TYPE = 1 IPMI_ASYNC_EVENT_RECV_TYPE = 2 IPMI_CMD_RECV_TYPE = 3 IPMI_RESPONSE_RESPONSE_TYPE = 4 IPMI_OEM_RECV_TYPE = 5 IPMI_MAINTENANCE_MODE_AUTO = 0 IPMI_MAINTENANCE_MODE_OFF = 1 IPMI_MAINTENANCE_MODE_ON = 2 IPMI_SYSTEM_INTERFACE_ADDR_TYPE = 0x0c IPMI_IPMB_ADDR_TYPE = 0x01 IPMI_IPMB_BROADCAST_ADDR_TYPE = 0x41 // broadcast get device id (IPMI 1.5 §17.9) IPMI_IPMB_DIRECT_ADDR_TYPE = 0x81 IPMI_LAN_ADDR_TYPE = 0x04 )
const BMCAddr uint8 = 0x20
BMCAddr is the conventional BMC slave address (0x20).
const DefaultTimeout time.Duration = time.Second * 10
DefaultTimeout is used when Backend.Send is called with timeout == 0.
const IPMI_IOC_MAGIC uintptr = 'i'
Variables ¶
var ( IPMICTL_SEND_COMMAND = IOW(IPMI_IOC_MAGIC, 13, unsafe.Sizeof(IPMI_REQ{})) IPMICTL_SEND_COMMAND_SETTIME = IOW(IPMI_IOC_MAGIC, 21, unsafe.Sizeof(IPMI_REQ_SETTIME{})) IPMICTL_RECEIVE_MSG = IOWR(IPMI_IOC_MAGIC, 12, unsafe.Sizeof(IPMI_RECV{})) IPMICTL_RECEIVE_MSG_TRUNC = IOWR(IPMI_IOC_MAGIC, 11, unsafe.Sizeof(IPMI_RECV{})) IPMICTL_REGISTER_FOR_CMD = IOR(IPMI_IOC_MAGIC, 14, unsafe.Sizeof(IPMI_CMDSPEC{})) IPMICTL_UNREGISTER_FOR_CMD = IOR(IPMI_IOC_MAGIC, 15, unsafe.Sizeof(IPMI_CMDSPEC{})) IPMICTL_REGISTER_FOR_CMD_CHANS = IOR(IPMI_IOC_MAGIC, 28, unsafe.Sizeof(IPMI_CMDSPEC_CHANS{})) IPMICTL_UNREGISTER_FOR_CMD_CHANS = IOR(IPMI_IOC_MAGIC, 29, unsafe.Sizeof(IPMI_CMDSPEC_CHANS{})) IPMICTL_SET_GETS_EVENTS_CMD = IOW(IPMI_IOC_MAGIC, 16, unsafe.Sizeof(uint32(0))) IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD = IOR(IPMI_IOC_MAGIC, 24, unsafe.Sizeof(IPMI_CHANNEL_LUN_ADDRESS_SET{})) IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD = IOR(IPMI_IOC_MAGIC, 25, unsafe.Sizeof(IPMI_CHANNEL_LUN_ADDRESS_SET{})) IPMICTL_SET_MY_CHANNEL_LUN_CMD = IOR(IPMI_IOC_MAGIC, 26, unsafe.Sizeof(IPMI_CHANNEL_LUN_ADDRESS_SET{})) IPMICTL_GET_MY_CHANNEL_LUN_CMD = IOR(IPMI_IOC_MAGIC, 27, unsafe.Sizeof(IPMI_CHANNEL_LUN_ADDRESS_SET{})) /* Legacy interfaces, these only set IPMB 0. */ IPMICTL_SET_MY_ADDRESS_CMD = IOR(IPMI_IOC_MAGIC, 17, unsafe.Sizeof(uint32(0))) IPMICTL_GET_MY_ADDRESS_CMD = IOR(IPMI_IOC_MAGIC, 18, unsafe.Sizeof(uint32(0))) IPMICTL_SET_MY_LUN_CMD = IOR(IPMI_IOC_MAGIC, 19, unsafe.Sizeof(uint32(0))) IPMICTL_GET_MY_LUN_CMD = IOR(IPMI_IOC_MAGIC, 20, unsafe.Sizeof(uint32(0))) IPMICTL_SET_TIMING_PARAMS_CMD = IOR(IPMI_IOC_MAGIC, 22, unsafe.Sizeof(IPMI_TIMING_PARAMS{})) IPMICTL_GET_TIMING_PARAMS_CMD = IOR(IPMI_IOC_MAGIC, 23, unsafe.Sizeof(IPMI_TIMING_PARAMS{})) IPMICTL_GET_MAINTENANCE_MODE_CMD = IOR(IPMI_IOC_MAGIC, 30, unsafe.Sizeof(uint32(0))) IPMICTL_SET_MAINTENANCE_MODE_CMD = IOW(IPMI_IOC_MAGIC, 31, unsafe.Sizeof(uint32(0))) )
Functions ¶
func OpenDevice ¶
OpenDevice opens the OpenIPMI character device for the given device number. It probes /dev/ipmiN, /dev/ipmi/N and /dev/ipmidev/N in order and returns the first path that opens successfully. When no path can be opened, the returned error lists every tried path with its individual failure reason.
Types ¶
type Backend ¶
type Backend interface {
Connect(ctx context.Context, devnum int32) error
Close(ctx context.Context) error
Send(ctx context.Context, req *Request, timeout time.Duration) ([]byte, error)
}
Backend abstracts an Open Interface transport: a local (in-band) path to the host BMC that tunnels a single system-interface-style IPMI request and returns the raw response.
Implementations:
- linux: DeviceBackend (OpenIPMI /dev/ipmiN)
- windows: COMBackend / PowerShellBackend (Microsoft_IPMI WMI)
All implementations return a byte slice whose first byte is the IPMI completion code and remaining bytes are the response payload.
func ResolveBackend ¶
func ResolveBackend(pref string, tryCOM, tryPS func() (Backend, error), onCOMFail func(error)) (Backend, error)
ResolveBackend picks a Backend from the preference string using two factory callbacks (COM and PowerShell). "" and BackendAuto try COM first and fall back to PowerShell on failure; an explicit BackendCOM or BackendPowerShell never falls back.
onCOMFail, if non-nil, is invoked with the COM error immediately before the PowerShell fallback attempt (auto path only).
type DeviceBackend ¶
type DeviceBackend struct {
// contains filtered or unexported fields
}
DeviceBackend implements Backend on top of the Linux OpenIPMI kernel driver (/dev/ipmiN).
func (*DeviceBackend) Close ¶
func (b *DeviceBackend) Close(ctx context.Context) error
Close closes the device file. Closing a backend that was never connected is a no-op.
type IPMI_ADDR ¶
type IPMI_ADDR struct {
AddrType int32
Channel uint16
Data [IPMI_MAX_ADDR_SIZE]byte
}
IPMI_ADDR is the generic openipmi address buffer.
type IPMI_CMDSPEC ¶
IPMI_CMDSPEC registers for commands from other entities on this interface.
type IPMI_CMDSPEC_CHANS ¶
type IPMI_IPMB_ADDR ¶
IPMI_IPMB_ADDR is used for IPMB / broadcast-IPMB destinations.
type IPMI_IPMB_DIRECT_ADDR ¶
type IPMI_IPMB_DIRECT_ADDR struct {
AddrType int32
Channel uint16
SlaveAddr uint8
RsLUN uint8
RqLUN uint8
}
IPMI_IPMB_DIRECT_ADDR is for messages received directly from an IPMB.
type IPMI_LAN_ADDR ¶
type IPMI_LAN_ADDR struct {
AddrType int32
Channel uint16
Privilege uint8
SessionHandle uint8
RemoteSWID uint8
LocalSWID uint8
LUN uint8
}
IPMI_LAN_ADDR is an address to/from a LAN interface bridged by the BMC.
type IPMI_MSG ¶
IPMI_MSG is the openipmi message body (no addressing). Response data's first byte is the completion code. Size is 16 on amd64.
type IPMI_REQ ¶
IPMI_REQ mirrors struct ipmi_req. Size is 40 on amd64; ioctl numbers encode it. DeviceBackend only — not the Backend.Send public protocol (see Request).
type IPMI_REQ_SETTIME ¶
IPMI_REQ_SETTIME mirrors struct ipmi_req_settime.
type IPMI_SYSTEM_INTERFACE_ADDR ¶
IPMI_SYSTEM_INTERFACE_ADDR is used for direct BMC system-interface messages.
type IPMI_TIMING_PARAMS ¶
type Request ¶
type Request struct {
NetFn uint8
Cmd uint8
// LUN is the responder LUN (low 2 bits of NetFn/LUN on the system
// interface; ipmi_addr.lun / WMI Lun on IPMB paths).
LUN uint8
// Data is the command request body (may be nil or empty).
Data []byte
// TargetAddr is the destination slave address. 0 means the local
// system interface (ipmitool open.c). Non-zero and different from
// MyAddr routes via IPMB / WMI ResponderAddress.
TargetAddr uint8
// TargetChannel is the IPMB channel (low 4 bits). Ignored for the
// local system interface.
TargetChannel uint8
// MyAddr is this open interface's own IPMB address. 0 is treated as
// BMCAddr. Used by the Linux backend for system-interface vs IPMB
// routing; ignored by Windows WMI backends.
MyAddr uint8
}
Request is the transport-neutral Open Interface request handed to Backend.Send. It carries the system-interface command body (NetFn/LUN/Cmd/Data — IPMI v2.0 §9.2 / §10.14 / §11.1) plus a logical destination. Individual backends map this onto their native plumbing:
- Linux DeviceBackend → openipmi ioctl (struct ipmi_req + ipmi_addr)
- Windows COM/PS → Microsoft_IPMI::RequestResponse parameters
This type deliberately does NOT mirror the Linux UAPI layout; ioctl structs live in uapi_linux.go.
func (*Request) EffectiveMyAddr ¶
EffectiveMyAddr returns MyAddr, substituting BMCAddr when zero.
func (*Request) EffectiveTarget ¶
EffectiveTarget returns TargetAddr, substituting BMCAddr when zero. Used by Windows WMI (ResponderAddress); Linux addressing treats a raw TargetAddr of 0 as "system interface" instead.