nell 0.3.0

Linux netlink interface
Documentation
// Copyright (C) 2020 - Will Glozer. All rights reserved.

use std::os::raw::c_int;
use anyhow::Result;
use nell::{Family, Socket};
use nell::ffi::*;
use nell::sys::socket::{Name, Level};

#[test]
#[cfg_attr(miri, ignore)]
fn add_drop_membership() -> Result<()> {
    let sock = Socket::new(Family::ROUTE)?;

    sock.add_membership(RTNLGRP_LINK)?;
    sock.add_membership(RTNLGRP_IPV4_IFADDR)?;
    sock.add_membership(RTNLGRP_IPV6_IFADDR)?;

    let groups = sock.list_memberships()?;

    assert!(groups[0] & RTMGRP_LINK        == RTMGRP_LINK);
    assert!(groups[0] & RTMGRP_IPV4_IFADDR == RTMGRP_IPV4_IFADDR);
    assert!(groups[0] & RTMGRP_IPV6_IFADDR == RTMGRP_IPV6_IFADDR);

    sock.drop_membership(RTNLGRP_LINK)?;
    sock.drop_membership(RTNLGRP_IPV4_IFADDR)?;
    sock.drop_membership(RTNLGRP_IPV6_IFADDR)?;

    let groups = sock.list_memberships()?;

    assert_eq!(0, groups[0]);

    Ok(())
}

#[test]
#[cfg_attr(miri, ignore)]
fn get_set_sockopt() -> Result<()> {
    const NETLINK: Level = Level::NETLINK;
    const CAP_ACK: Name  = Name::NETLINK_CAP_ACK;

    let sock = Socket::new(Family::ROUTE)?;

    let on:  c_int = 1;
    let off: c_int = 0;

    assert_eq!(off, sock.get_sockopt(NETLINK, CAP_ACK)?);
    sock.set_sockopt(NETLINK, CAP_ACK, &on)?;
    assert_eq!(on,  sock.get_sockopt(NETLINK, CAP_ACK)?);

    Ok(())
}