netlink-rust 0.1.1

Netlink library in Rust
Documentation
use libc;
use std::io;
use std::mem::size_of;
use std::os::unix::io::RawFd;

#[repr(C)]
pub struct Address {
    pub family: u16,
    pub _pad: u16,
    pub pid: u32,
    pub groups: u32,
}

macro_rules! ccall {
    ( $x:expr ) => {{
        let value = unsafe { $x };
        if value < 0 {
            return Err(io::Error::last_os_error());
        }
        value
    }};
}

pub fn get_page_size() -> usize {
    unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
}

pub fn netlink_socket(service: i32) -> io::Result<RawFd> {
    Ok(ccall!(libc::socket(
        libc::AF_NETLINK,
        libc::SOCK_RAW | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC,
        service
    )))
}

pub fn set_socket_option<T: Sized>(
    socket: RawFd,
    level: i32,
    name: i32,
    value: T,
) -> io::Result<()> {
    let value_ptr: *const T = &value;
    ccall!(libc::setsockopt(
        socket,
        level,
        name,
        value_ptr as *mut libc::c_void,
        size_of::<T>() as u32
    ));
    Ok(())
}

pub fn bind(socket: RawFd, address: &Address) -> io::Result<()> {
    let addr_ptr: *const Address = address;
    ccall!(libc::bind(
        socket,
        addr_ptr as *const libc::sockaddr,
        size_of::<Address>() as u32
    ));
    Ok(())
}

pub fn get_socket_address(socket: RawFd, address: &mut Address) -> io::Result<()> {
    let addr_ptr = address as *mut Address as *mut libc::sockaddr;
    let mut addr_len = size_of::<Address>() as libc::socklen_t;
    let addr_len_ptr: *mut libc::socklen_t = &mut addr_len;
    ccall!(libc::getsockname(socket, addr_ptr, addr_len_ptr));
    Ok(())
}

pub fn send_message(socket: RawFd, header: &libc::msghdr, flags: i32) -> io::Result<usize> {
    Ok(ccall!(libc::sendmsg(socket, header as *const libc::msghdr, flags)) as usize)
}

pub fn receive_message(socket: RawFd, header: &mut libc::msghdr) -> io::Result<usize> {
    Ok(ccall!(libc::recvmsg(socket, header as *mut libc::msghdr, 0)) as usize)
}

pub fn send(socket: RawFd, data: &[u8], flags: i32) -> io::Result<usize> {
    Ok(ccall!(libc::send(
        socket,
        data.as_ptr() as *const libc::c_void,
        data.len(),
        flags
    )) as usize)
}