1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
// SPDX-License-Identifier: MIT
// Build:
//
// ```
// cd netlink-sys
// cargo build --example audit_events_async --features tokio_socket
// ```
//
// Run *as root*:
//
// ```
// ../target/debug/examples/audit_events_async
// ```
use std::process;
use netlink_packet_audit::{
AuditMessage, NetlinkBuffer, NetlinkMessage, StatusMessage, NLM_F_ACK,
NLM_F_REQUEST,
};
use netlink_sys::{
protocols::NETLINK_AUDIT, AsyncSocket, AsyncSocketExt, SocketAddr,
TokioSocket,
};
const AUDIT_STATUS_ENABLED: u32 = 1;
const AUDIT_STATUS_PID: u32 = 4;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let kernel_unicast: SocketAddr = SocketAddr::new(0, 0);
let mut socket = TokioSocket::new(NETLINK_AUDIT).unwrap();
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;
nl_msg.finalize();
let mut buf = vec![0; 1024 * 8];
nl_msg.serialize(&mut buf[..nl_msg.buffer_len()]);
println!(">>> {:?}", nl_msg);
socket
.send_to(&buf[..nl_msg.buffer_len()], &kernel_unicast)
.await
.unwrap();
let mut buf = bytes::BytesMut::with_capacity(1024 * 8);
loop {
buf.clear();
let _addr = socket.recv_from(&mut buf).await.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 n = buf.len();
let mut nl_buf = NetlinkBuffer::new(&mut buf);
if n != nl_buf.length() as usize {
nl_buf.set_length(n as u32);
}
}
let parsed = NetlinkMessage::<AuditMessage>::deserialize(&buf).unwrap();
println!("<<< {:?}", parsed);
}
}
|