slmp-rs

Seamless Message Protocol (SLMP) for Rust

This library provides SLMP client to access the PLCs of Mitsubishi Electric

Get Started

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;
}

Access Method

SLMP provides roughly 5 categories;

This library supports device access and unit control methods.

Device Control

This library enable you to use

and primitive types

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_read

Unit Control

This library supports

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_control

Debugging Proxy

To check transferred data between a client and server, you can use a debugging-proxy server.

cargo r --example debugging_proxy

This could be used by setting IP/port of a proxy server on SLMP4EConnectionProps instead of setting those of a SLMP server.

Multi-PLC Connection

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_read

[!CAUTION] 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.

In response to the above reports, Mitsubishi Electric has implemented the following countermeasures (as stated in advisory 2025-08-28):

(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.