| Crates.io | ruipmi |
| lib.rs | ruipmi |
| version | 0.2.0 |
| created_at | 2025-10-22 06:05:30.918511+00 |
| updated_at | 2025-10-22 06:18:10.250717+00 |
| description | An asynchronous IPMI client library implemented in Rust using Tokio. |
| homepage | |
| repository | https://github.com/dalof41014/ruipmi |
| max_upload_size | |
| id | 1895051 |
| size | 62,474 |
ruipmi is a minimal asynchronous RMCP+ IPMI client written in Rust.
It implements the IPMI v2.0 LAN+ session handshake (Open Session + RAKP1–4) and provides encrypted message transmission over UDP using AES-CBC-128 and HMAC-SHA256 integrity/authentication.
✅ Asynchronous UDP networking (based on tokio::net::UdpSocket)
✅ Full RMCP+ session establishment:
✅ Cipher suite support:
HMAC-SHA1, HMAC-MD5, HMAC-SHA256HMAC-SHA1-96, HMAC-SHA256-128, HMAC-MD5-128AES-CBC-128 or None✅ Automatic SIK / K1 / K2 derivation
✅ IPMB encapsulation support (for bridging to other BMCs)
✅ Clean modular design for embedding in higher-level management tools
| Layer | Function |
|---|---|
| RMCP Header | 4 bytes (0x06 00 FF 07) |
| RMCP+ Session Header | 12 bytes (AuthType, PayloadType, SessionID, Seq, PayloadLen) |
| Payload | Open/RAKP/IPMI command body |
| Integrity Trailer | Padding, Next Header, HMAC digest |
Internally, the client implements:
build_open_session_request()build_rakp1(), build_rakp3()build_v2_encrypted_msg()decode_and_decrypt()[dependencies]
tokio = { version = "1.40", features = ["full"] }
aes = "0.8"
cbc = "0.1"
hmac = "0.12"
md-5 = "0.10"
sha1 = "0.10"
sha2 = "0.10"
rand = "0.8"
thiserror = "1.0"
log = "0.4"
Create a small async test file (e.g. examples/demo.rs):
use ruipmi::IpmiClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = IpmiClient::new(
"10.0.0.5", // BMC hostname or IP
"admin",
"password",
None, // use default cipher suite
None,
None,
).await?;
client.connect().await?;
println!("RMCP+ session established.");
// Example: Send Close Session command
client.close().await?;
println!("Session closed.");
Ok(())
}
Run it:
cargo run --example demo
| Method | Description |
|---|---|
new(host, user, pass, cipher, ch, tgt) |
Create an IpmiClient bound to an ephemeral UDP port |
connect() |
Perform RMCP+ session handshake (OpenSession + RAKP1–4) |
request(&[u8]) |
Send one IPMI command (encrypted + HMAC verified) |
close() |
Gracefully close the current session |
build_ipmb_send_message() |
Wrap a raw command in IPMB SEND_MESSAGE format |
The default cipher suite matches ID 17 from the IPMI 2.0 table:
| Field | Algorithm |
|---|---|
| Authentication | HMAC-SHA256 |
| Integrity | HMAC-SHA256-128 |
| Confidentiality | AES-CBC-128 |
To customize:
use ruipmi::{CipherSuite, AuthAlg, IntegrityAlg, CryptAlg};
let cipher = CipherSuite {
authentication: AuthAlg::HmacSha1,
integrity: IntegrityAlg::HmacSha1_96,
confidentiality: CryptAlg::None,
};
let client = IpmiClient::new("host", "user", "pass", Some(cipher), None, None).await?;
IPMI_CMD_TIMEOUT_SECS) are enforced via tokio::time::timeout.log::debug! and can be enabled with:RUST_LOG=debug cargo run --example demo
Local build and syntax check:
cargo check
cargo test
Run an example (requires reachable BMC endpoint):
cargo run --example demo