netlink-rust 0.1.0

Netlink library in Rust
Documentation
use libc;
use std::mem::size_of;
use std::io;
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(socket: RawFd, level: i32, name: i32, value: i32) -> io::Result<()>
{
    let value_ptr: *const i32 = &value;
    ccall!(libc::setsockopt(socket, level, name, value_ptr as *mut libc::c_void,
        size_of::<i32>() 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)
}