Struct netlink_sys::Socket
source · pub struct Socket(/* private fields */);
Expand description
A netlink socket.
§Example
In this example we:
- open a new socket
- send a message to the kernel
- read the reponse
use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr};
use std::process;
// open a new socket for the NETLINK_ROUTE subsystem (see "man 7 rtnetlink")
let mut socket = Socket::new(NETLINK_ROUTE).unwrap();
// address of the remote peer we'll send a message to. This particular address is for the kernel
let kernel_addr = SocketAddr::new(0, 0);
// this is a valid message for listing the network links on the system
let pkt = vec![
0x14, 0x00, 0x00, 0x00, 0x12, 0x00, 0x01, 0x03, 0xfd, 0xfe, 0x38, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
];
// send the message to the kernel
let n_sent = socket.send_to(&pkt[..], &kernel_addr, 0).unwrap();
assert_eq!(n_sent, pkt.len());
// buffer for receiving the response
let mut buf = vec![0; 4096];
loop {
// receive a datagram
let (n_received, sender_addr) = socket.recv_from(&mut &mut buf[..], 0).unwrap();
assert_eq!(sender_addr, kernel_addr);
println!("received datagram {:?}", &buf[..n_received]);
if buf[4] == 2 && buf[5] == 0 {
println!("the kernel responded with an error");
return;
}
if buf[4] == 3 && buf[5] == 0 {
println!("end of dump");
return;
}
}
Implementations§
source§impl Socket
impl Socket
sourcepub fn new(protocol: isize) -> Result<Self>
pub fn new(protocol: isize) -> Result<Self>
Open a new socket for the given netlink subsystem. protocol
must be
one of the netlink_sys::protocols
constants.
sourcepub fn bind(&mut self, addr: &SocketAddr) -> Result<()>
pub fn bind(&mut self, addr: &SocketAddr) -> Result<()>
Bind the socket to the given address
sourcepub fn bind_auto(&mut self) -> Result<SocketAddr>
pub fn bind_auto(&mut self) -> Result<SocketAddr>
Bind the socket to an address assigned by the kernel, and return that address.
sourcepub fn get_address(&self, addr: &mut SocketAddr) -> Result<()>
pub fn get_address(&self, addr: &mut SocketAddr) -> Result<()>
Get the socket address
sourcepub fn set_non_blocking(&self, non_blocking: bool) -> Result<()>
pub fn set_non_blocking(&self, non_blocking: bool) -> Result<()>
Make this socket non-blocking
sourcepub fn connect(&self, remote_addr: &SocketAddr) -> Result<()>
pub fn connect(&self, remote_addr: &SocketAddr) -> Result<()>
Connect the socket to the given address. Netlink is a connection-less
protocol, so a socket can communicate with multiple peers with the
Socket::send_to
and Socket::recv_from
methods. However, if the
socket only needs to communicate with one peer, it is convenient not
to have to bother with the peer address. This is what connect
is
for. After calling connect
, Socket::send
and Socket::recv
respectively send and receive datagrams to and from remote_addr
.
§Examples
In this example we:
- open a socket
- connect it to the kernel with
Socket::connect
- send a request to the kernel with
Socket::send
- read the response (which can span over several messages)
Socket::recv
use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr};
use std::process;
let mut socket = Socket::new(NETLINK_ROUTE).unwrap();
let _ = socket.bind_auto().unwrap();
let kernel_addr = SocketAddr::new(0, 0);
socket.connect(&kernel_addr).unwrap();
// This is a valid message for listing the network links on the system
let msg = vec![
0x14, 0x00, 0x00, 0x00, 0x12, 0x00, 0x01, 0x03, 0xfd, 0xfe, 0x38, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
];
let n_sent = socket.send(&msg[..], 0).unwrap();
assert_eq!(n_sent, msg.len());
// buffer for receiving the response
let mut buf = vec![0; 4096];
loop {
let mut n_received = socket.recv(&mut &mut buf[..], 0).unwrap();
println!("received {:?}", &buf[..n_received]);
if buf[4] == 2 && buf[5] == 0 {
println!("the kernel responded with an error");
return;
}
if buf[4] == 3 && buf[5] == 0 {
println!("end of dump");
return;
}
}
sourcepub fn recv_from<B>(
&self,
buf: &mut B,
flags: c_int
) -> Result<(usize, SocketAddr)>where
B: BufMut,
pub fn recv_from<B>(
&self,
buf: &mut B,
flags: c_int
) -> Result<(usize, SocketAddr)>where
B: BufMut,
Read a datagram from the socket and return the number of bytes that have
been read and the address of the sender. The data being read is
copied into buf
. If buf
is too small, the datagram is truncated. The
supported flags are the MSG_*
described in man 2 recvmsg
§Warning
In datagram oriented protocols, recv
and recvfrom
receive normally
only ONE datagram, but this seems not to be always true for netlink
sockets: with some protocols like NETLINK_AUDIT
, multiple netlink
packets can be read with a single call.
sourcepub fn recv<B>(&self, buf: &mut B, flags: c_int) -> Result<usize>where
B: BufMut,
pub fn recv<B>(&self, buf: &mut B, flags: c_int) -> Result<usize>where
B: BufMut,
For a connected socket, recv
reads a datagram from the socket. The
sender is the remote peer the socket is connected to (see
Socket::connect
). See also Socket::recv_from
sourcepub fn recv_from_full(&self) -> Result<(Vec<u8>, SocketAddr)>
pub fn recv_from_full(&self) -> Result<(Vec<u8>, SocketAddr)>
Receive a full message. Unlike Socket::recv_from
, which truncates
messages that exceed the length of the buffer passed as argument,
this method always reads a whole message, no matter its size.
sourcepub fn send_to(
&self,
buf: &[u8],
addr: &SocketAddr,
flags: c_int
) -> Result<usize>
pub fn send_to( &self, buf: &[u8], addr: &SocketAddr, flags: c_int ) -> Result<usize>
Send the given buffer buf
to the remote peer with address addr
. The
supported flags are the MSG_*
values documented in man 2 send
.
sourcepub fn send(&self, buf: &[u8], flags: c_int) -> Result<usize>
pub fn send(&self, buf: &[u8], flags: c_int) -> Result<usize>
For a connected socket, send
sends the given buffer buf
to the
remote peer the socket is connected to. See also Socket::connect
and Socket::send_to
.
pub fn set_pktinfo(&mut self, value: bool) -> Result<()>
pub fn get_pktinfo(&self) -> Result<bool>
pub fn add_membership(&mut self, group: u32) -> Result<()>
pub fn drop_membership(&mut self, group: u32) -> Result<()>
sourcepub fn set_broadcast_error(&mut self, value: bool) -> Result<()>
pub fn set_broadcast_error(&mut self, value: bool) -> Result<()>
NETLINK_BROADCAST_ERROR
(since Linux 2.6.30). When not set,
netlink_broadcast()
only reports ESRCH
errors and silently
ignore NOBUFS
errors.
pub fn get_broadcast_error(&self) -> Result<bool>
sourcepub fn set_no_enobufs(&mut self, value: bool) -> Result<()>
pub fn set_no_enobufs(&mut self, value: bool) -> Result<()>
NETLINK_NO_ENOBUFS
(since Linux 2.6.30). This flag can be used by
unicast and broadcast listeners to avoid receiving ENOBUFS
errors.
pub fn get_no_enobufs(&self) -> Result<bool>
sourcepub fn set_listen_all_namespaces(&mut self, value: bool) -> Result<()>
pub fn set_listen_all_namespaces(&mut self, value: bool) -> Result<()>
NETLINK_LISTEN_ALL_NSID
(since Linux 4.2). When set, this socket will
receive netlink notifications from all network namespaces that
have an nsid assigned into the network namespace where the socket
has been opened. The nsid is sent to user space via an ancillary
data.
pub fn get_listen_all_namespaces(&self) -> Result<bool>
sourcepub fn set_cap_ack(&mut self, value: bool) -> Result<()>
pub fn set_cap_ack(&mut self, value: bool) -> Result<()>
NETLINK_CAP_ACK
(since Linux 4.2). The kernel may fail to allocate the
necessary room for the acknowledgment message back to user space.
This option trims off the payload of the original netlink message.
The netlink message header is still included, so the user can
guess from the sequence number which message triggered the
acknowledgment.
pub fn get_cap_ack(&self) -> Result<bool>
sourcepub fn set_ext_ack(&mut self, value: bool) -> Result<()>
pub fn set_ext_ack(&mut self, value: bool) -> Result<()>
NETLINK_EXT_ACK
Extended ACK controls reporting of additional error/warning TLVs in
NLMSG_ERROR and NLMSG_DONE messages.
pub fn get_ext_ack(&self) -> Result<bool>
sourcepub fn set_rx_buf_sz<T>(&self, size: T) -> Result<()>
pub fn set_rx_buf_sz<T>(&self, size: T) -> Result<()>
Sets socket receive buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead), and this doubled value is returned by [get_rx_buf_sz].(see socket(7) The default value is set by the proc/sys/net/core/rmem_default file, and the maximum allowed value is set by the /proc/sys/net/core/rmem_max file. The minimum (doubled) value for this option is 256.
sourcepub fn get_rx_buf_sz(&self) -> Result<usize>
pub fn get_rx_buf_sz(&self) -> Result<usize>
Gets socket receive buffer in bytes
sourcepub fn set_netlink_get_strict_chk(&self, value: bool) -> Result<()>
pub fn set_netlink_get_strict_chk(&self, value: bool) -> Result<()>
Set strict input checking(NETLINK_GET_STRICT_CHK
) in netlink route
protocol. By default, NETLINK_GET_STRICT_CHK
is not enabled.