Crates.io | netlink-packet-connector |
lib.rs | netlink-packet-connector |
version | 0.1.0 |
created_at | 2025-07-13 15:45:09.300678+00 |
updated_at | 2025-07-13 15:45:09.300678+00 |
description | An implementation of the Linux kernel Connector API using netlink-packet-core. |
homepage | |
repository | https://gitlab.com/hpi-potsdam/osm/webassembly-kernel-runtime/netlink-packet-connector |
max_upload_size | |
id | 1750600 |
size | 22,626 |
This crate implements the Netlink-based Connector API used for communication between Linux kernel and user space.
To do so, it relies on the netlink-packet-core
crate and is aligned to the rust-netlink crates.
An example usage could look like the following:
use bytes::Buf;
use log::info;
use netlink_packet_connector::protocol::ConnectorMessage;
use netlink_packet_core::{NetlinkBuffer, NetlinkDeserializable, NetlinkMessage, NetlinkPayload};
use netlink_sys::{protocols::NETLINK_CONNECTOR, Socket, SocketAddr};
fn main() {
// Example connector API message with seq number 1234 and a single byte data payload.s
let connector_message = ConnectorMessage::new(15, 1001, 1234, 0, 0, vec![1]);
let mut nl_msg = NetlinkMessage::from(connector_message);
nl_msg.finalize();
let mut buf = vec![0; 1024 * 8];
nl_msg.serialize(&mut buf[..nl_msg.buffer_len()]);
// ... `socket` is a netlink socket
socket.bind(&kernel_unicast).unwrap();
socket.add_membership(14).unwrap();
socket.send(&buf[..nl_msg.buffer_len()], 0).unwrap();
info!("WebAssembly runtime CLI started!");
let mut buf = Vec::with_capacity(1024 * 8);
let n = socket.recv(&mut buf, 0).unwrap();
// This dance with the NetlinkBuffer should not be
// necessary. It is here to work around a netlink bug. See:
// https://github.com/mozilla/libaudit-go/issues/24
// https://github.com/linux-audit/audit-userspace/issues/78
{
let mut nl_buf = NetlinkBuffer::new(&mut buf[0..n]);
if n != nl_buf.length() as usize {
nl_buf.set_length(n as u32);
}
}
// Parse an received Connector API message
let parsed = NetlinkMessage::<ConnectorMessage>::deserialize(&buf[0..n]).unwrap();
match parsed.payload {
NetlinkPayload::InnerMessage(connector_msg) => {
info!("Received connector message: {:?}", connector_msg.data());
}
NetlinkPayload::Done(msg) => {
let mut payload = msg.code.to_ne_bytes().to_vec();
payload.extend_from_slice(&msg.extended_ack);
let connector_ack = ConnectorMessage::deserialize(&parsed.header, &payload).unwrap();
info!("Received connector ack: {:?}", connector_ack.data());
// TODO: do something
}
_ => {
info!("Received something else: {:?}", parsed);
}
}
}