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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
extern crate libc;

use std::mem;
use libc::{c_int, c_void};
use ::message::{NetlinkMessage, nl_msg};
use ::message::expose::{nl_msg_ptr};


#[link(name="nl-3")]
extern "C" {
    fn nla_put(msg: *const nl_msg, attrtype: c_int, datalen: c_int, data: *const c_void) -> i32;
    fn nla_put_nested(msg: *const nl_msg, attrtype: c_int, nested: *const nl_msg) -> i32;
}


pub enum Type {
    Unspec,
    U8,
    U16,
    U32,
    U64,
    String,
    Flag,
    Msecs,
    Nested,
    __Max
}

pub fn put<T>(msg: &mut NetlinkMessage, atype: i32, len: u32, data: &T) -> i32 {
    unsafe{ 
        let vptr: *const c_void = mem::transmute(data);
        nla_put(::message::expose::nl_msg_ptr(msg), atype as c_int, len as c_int, vptr) 
    }
}

pub fn put_no_data(msg: &mut NetlinkMessage, atype: i32) -> i32 {
    unsafe{ nla_put(::message::expose::nl_msg_ptr(msg), atype as c_int, 0, 0x0 as *const c_void) }
}

pub fn put_nested(msg: &mut NetlinkMessage, atype: i32, nested: &NetlinkMessage) -> i32 {
    unsafe { nla_put_nested(nl_msg_ptr(msg), atype as c_int, nl_msg_ptr(nested)) }
}

#[macro_export]
macro_rules! NlaPutU8 {
        ($msg:expr, $atype: expr, $data:expr) => {
            rsnl::attribute::put($msg, $atype, std::mem::size_of::<u8>() as u32, $data)
        }
}

#[macro_export]
macro_rules! NlaPutU16 {
        ($msg:expr, $atype: expr, $data:expr) => {
            rsnl::attribute::put($msg, $atype, std::mem::size_of::<u16>() as u32, $data)
        }
}

#[macro_export]
macro_rules! NlaPutU32 {
        ($msg:expr, $atype: expr, $data:expr) => {
            rsnl::attribute::put($msg, $atype, std::mem::size_of::<u32>() as u32, $data)
        }
}

#[macro_export]
macro_rules! NlaPutU64 {
        ($msg:expr, $atype: expr, $data:expr) => {
            rsnl::attribute::put($msg, $atype, std::mem::size_of::<u64>() as u32, $data)
        }
}

#[macro_export]
macro_rules! NlaPutMsec {
        ($msg:expr, $atype: expr, $msecs:expr) => {
            rsnl::attribute::put($msg, $atype, std::mem::size_of::<u64>() as u32, $msecs)
        }
}

#[macro_export]
macro_rules! NlaPutFlag {
        ($msg:expr, $atype: expr) => {
            rsnl::attribute::put_no_data($msg, $atype)
        }
}

// TODO:
// NlaPutAddr!()
// NlaPutData!()
// NlaPutFlag!()
// NlaPutString!()