[−][src]Crate netlink_proto
netlink-proto
is an asynchronous implementation of the Netlink
protocol.
Example: listening for audit events
This example shows how to use netlink-proto
with the tokio
runtime to print audit events. It requires extra external
dependencies:
futures = "^0.3"
tokio = "^0.2"
netlink-packet-audit = "^0.1"
use futures::stream::StreamExt; use netlink_packet_audit::{ NLM_F_ACK, NLM_F_REQUEST, NetlinkMessage, NetlinkPayload, AuditMessage, StatusMessage, }; use std::process; use netlink_proto::{ new_connection, sys::{SocketAddr, protocols::NETLINK_AUDIT}, }; const AUDIT_STATUS_ENABLED: u32 = 1; const AUDIT_STATUS_PID: u32 = 4; #[tokio::main] async fn main() -> Result<(), String> { // Create a netlink socket. Here: // // - `conn` is a `Connection` that has the netlink socket. It's a // `Future` that keeps polling the socket and must be spawned an // the event loop. // // - `handle` is a `Handle` to the `Connection`. We use it to send // netlink messages and receive responses to these messages. // // - `messages` is a channel receiver through which we receive // messages that we have not solicited, ie that are not // response to a request we made. In this example, we'll receive // the audit event through that channel. let (conn, mut handle, mut messages) = new_connection(NETLINK_AUDIT) .map_err(|e| format!("Failed to create a new netlink connection: {}", e))?; // Spawn the `Connection` so that it starts polling the netlink // socket in the background. tokio::spawn(conn); // Use the `ConnectionHandle` to send a request to the kernel // asking it to start multicasting audit event messages. tokio::spawn(async move { // Craft the packet to enable audit events let mut status = StatusMessage::new(); status.enabled = 1; status.pid = process::id(); status.mask = AUDIT_STATUS_ENABLED | AUDIT_STATUS_PID; let payload = AuditMessage::SetStatus(status); let mut nl_msg = NetlinkMessage::from(payload); nl_msg.header.flags = NLM_F_REQUEST | NLM_F_ACK; // We'll send unicast messages to the kernel. let kernel_unicast: SocketAddr = SocketAddr::new(0, 0); let mut response = match handle.request(nl_msg, kernel_unicast) { Ok(response) => response, Err(e) => { eprintln!("{}", e); return; } }; while let Some(message) = response.next().await { if let NetlinkPayload::Error(err_message) = message.payload { eprintln!("Received an error message: {:?}", err_message); return; } } }); // Finally, start receiving event through the `messages` channel. println!("Starting to print audit events... press ^C to interrupt"); while let Some((message, _addr)) = messages.next().await { if let NetlinkPayload::Error(err_message) = message.payload { eprintln!("received an error message: {:?}", err_message); } else { println!("{:?}", message); } } Ok(()) }
Example: dumping all the machine's links
This example shows how to use netlink-proto
with the ROUTE
protocol.
Here we do not use netlink_proto::new_connection()
, and instead
create the socket manually and use call send()
and receive()
directly. In the previous example, the NetlinkFramed
was wrapped
in a Connection
which was polled automatically by the runtime.
use futures::StreamExt; use netlink_packet_route::{ NLM_F_DUMP, NLM_F_REQUEST, NetlinkMessage, NetlinkHeader, LinkMessage, RtnlMessage }; use netlink_proto::{ new_connection, sys::{SocketAddr, protocols::NETLINK_ROUTE}, }; #[tokio::main] async fn main() -> Result<(), String> { // Create the netlink socket. Here, we won't use the channel that // receives unsolicited messages. let (conn, mut handle, _) = new_connection(NETLINK_ROUTE) .map_err(|e| format!("Failed to create a new netlink connection: {}", e))?; // Spawn the `Connection` in the background tokio::spawn(conn); // Create the netlink message that requests the links to be dumped let msg = NetlinkMessage { header: NetlinkHeader { sequence_number: 1, flags: NLM_F_DUMP | NLM_F_REQUEST, ..Default::default() }, payload: RtnlMessage::GetLink(LinkMessage::default()).into(), }; // Send the request let mut response = handle .request(msg, SocketAddr::new(0, 0)) .map_err(|e| format!("Failed to send request: {}", e))?; // Print all the messages received in response loop { if let Some(packet) = response.next().await { println!("<<< {:?}", packet); } else { break; } } Ok(()) }
Re-exports
pub use netlink_packet_core as packet; |
Modules
sys |
Structs
Connection | Connection to a Netlink socket, running in the background. |
ConnectionHandle | A handle to pass requests to a |
Error | |
NetlinkCodec | |
NetlinkFramed |
Enums
ErrorKind |
Functions
new_connection | Create a new Netlink connection for the given Netlink protocol, and returns a handle to that
connection as well as a stream of unsolicited messages received by that connection (unsolicited
here means messages that are not a response to a request made by the |