This library provides SLMP client to access the PLCs of Mitsubishi Electric
First of all, You should enable SLMP communication (binary mode) and open a port using GX Works 2/3.
This library supports the connection to MELSEC-Q and MELSEC iQ-R PLCs, using a 4E frame.
You can pass a connection property with new() and try to connect with connect().
use slmp::{SLMPClient, SLMP4EConnectionProps};
#[tokio::main]
async fn main() {
const conn_props: SLMP4EConnectionProps = SLMP4EConnectionProps {...};
let mut client = SLMPClient::new(conn_props);
client.connect().await.unwrap();
...
client.close().await;
}SLMP provides roughly 5 categories;
- Device access
- Label access
- Buffer-memory access
- Unit control
- File control
This library supports device access and unit control methods.
This library enable you to use
- Bulk read/write
- Random read/write
- Block read/write
- Monitor register/read
and primitive types
- bool
- [bool; 16] (Word-size access)
- u16
- i16
- u32
- i32
- f32
- f64
- String
The samples of those methods are prepared in /examples:
cargo r --example bulk_access
cargo r --example random_access
cargo r --example block_access
cargo r --example monitor_readThis library supports
- Remote run
- Remote stop
- Remote pause
- Remote latch clear
- Remote reset *
- Get cpu type
- Remote unlock
- Remote lock
- Echo
- Error Clear (for serial communication unit)
There are restrictions on use of remote reset. Please check the document from Mitsubishi Electric.
The sample is prepared in /examples:
cargo r --example unit_controlTo check transferred data between a client and server, you can use a debugging-proxy server.
cargo r --example debugging_proxyThis could be used by setting IP/port of a proxy server on SLMP4EConnectionProps instead of setting those of a SLMP server.
SLMPConnectionManager allows you to connect a client to multi PLCs.
You can give a cyclic task to each connection.
use slmp::{CPU, SLMP4EConnectionProps, SLMPConnectionManager};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let manager = SLMPConnectionManager::new();
const conn_props_1: SLMP4EConnectionProps = SLMP4EConnectionProps {...};
const conn_props_2: SLMP4EConnectionProps = SLMP4EConnectionProps {...};
let cyclic_task = async |data| {
for x in data {
println!("{:?}", x);
}
println!();
Ok(())
};
manager.connect(conn_props_1, cyclic_task).await?;
manager.connect(conn_props_2, cyclic_task).await?;
...
manager.disconnect(conn_props_1).await?;
manager.disconnect(conn_props_2).await?;
Ok(())
}The sample of cyclic read is prepared in /examples:
cargo r --example cyclic_readCaution
The SLMP protocol features a concise presentation layer without any encryption, and it allows device modifications, file operations, and changes to CPU operation settings without any authentication.
The following vulnerabilities have been registered with CISA.
- CVE-2020-5594: Cleartext Transmission of Sensitive Information
- CVE-2020-16226: Impersonations of a Legitimate Device by a Malicious Actor
- CVE-2023-4699: Arbitrary Command Execution
- CVE-2025-7405: Missing Authentication for Critical Function
- CVE-2025-7731: Cleartext Transmission of Sensitive Information
In response to the above reports, Mitsubishi Electric has implemented the following countermeasures (as stated in advisory 2025-08-28):
- Use a virtual private network (VPN) or similar technology to encrypt SLMP communications.
- Restrict physical access to the LAN to which the affected products are connected.
(Note: No firmware fix is planned for this vulnerability.)
It should be noted that improper use of SLMP carries significant risks, which allow attacks like man-in-the-middle (MitM), impersonation/spoofing, denial-of-service (DoS). Please use it with caution.