From 75acb1b471ee9f31bbff09455ecb9a8b9c4c2183 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Wed, 17 May 2017 16:08:28 +0900 Subject: [PATCH 01/27] [examples] fix inet_ntop buf size --- examples/rtnl/rtnl-route-dump.rs | 4 ++-- examples/rtnl/rtnl-route-event.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/rtnl/rtnl-route-dump.rs b/examples/rtnl/rtnl-route-dump.rs index c233026..08d8bbb 100644 --- a/examples/rtnl/rtnl-route-dump.rs +++ b/examples/rtnl/rtnl-route-dump.rs @@ -30,10 +30,10 @@ impl AddrFamily for libc::in6_addr { } fn _inet_ntoa(addr: &T) -> String { - let mut buf = [0u8; INET_ADDRSTRLEN]; + let mut buf = [0u8; INET6_ADDRSTRLEN]; unsafe { let rs = inet_ntop(addr.family(), addr as *const _ as *const c_void, - buf.as_mut_ptr() as *mut c_char, INET_ADDRSTRLEN as socklen_t); + buf.as_mut_ptr() as *mut c_char, INET6_ADDRSTRLEN as socklen_t); CStr::from_ptr(rs).to_string_lossy().into_owned() } } diff --git a/examples/rtnl/rtnl-route-event.rs b/examples/rtnl/rtnl-route-event.rs index 60ba4d6..8fe831b 100644 --- a/examples/rtnl/rtnl-route-event.rs +++ b/examples/rtnl/rtnl-route-event.rs @@ -28,10 +28,10 @@ impl AddrFamily for libc::in6_addr { } fn _inet_ntoa(addr: &T) -> String { - let mut buf = [0u8; INET_ADDRSTRLEN]; + let mut buf = [0u8; INET6_ADDRSTRLEN]; unsafe { let rs = inet_ntop(addr.family(), addr as *const _ as *const c_void, - buf.as_mut_ptr() as *mut c_char, INET_ADDRSTRLEN as socklen_t); + buf.as_mut_ptr() as *mut c_char, INET6_ADDRSTRLEN as socklen_t); CStr::from_ptr(rs).to_string_lossy().into_owned() } } From 8b445f9a3b41d50b904d404cbcb2c5d43746f9fa Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Wed, 17 May 2017 16:16:54 +0900 Subject: [PATCH 02/27] [mnl] introduce closure which is better remaining with olds by function naming or delete it. Idiomatic callbacks in Rust http://stackoverflow.com/questions/41081240/idiomatic-callbacks-in-rust Returning a closure from a function http://stackoverflow.com/questions/25445761/returning-a-closure-from-a-function How do I convert a Rust closure to a C-style callback? http://stackoverflow.com/questions/32270030/how-do-i-convert-a-rust-closure-to-a-c-style-callback --- examples/rtnl-route-dump2.rs | 1 + examples/rtnl/rtnl-route-dump2.rs | 300 ++++++++++++++++++++++++++++++ src/lib.rs | 66 ++++++- tests/lib.rs | 39 ++++ 4 files changed, 405 insertions(+), 1 deletion(-) create mode 120000 examples/rtnl-route-dump2.rs create mode 100644 examples/rtnl/rtnl-route-dump2.rs diff --git a/examples/rtnl-route-dump2.rs b/examples/rtnl-route-dump2.rs new file mode 120000 index 0000000..6b42b50 --- /dev/null +++ b/examples/rtnl-route-dump2.rs @@ -0,0 +1 @@ +rtnl/rtnl-route-dump2.rs \ No newline at end of file diff --git a/examples/rtnl/rtnl-route-dump2.rs b/examples/rtnl/rtnl-route-dump2.rs new file mode 100644 index 0000000..0d65aa4 --- /dev/null +++ b/examples/rtnl/rtnl-route-dump2.rs @@ -0,0 +1,300 @@ +use std::env; +use std::io::Write; +use std::mem::size_of; +use std::ffi::CStr; + +extern crate libc; +extern crate time; +extern crate crslmnl as mnl; +use libc::{ c_int, c_char, c_void, socklen_t }; + +use mnl::linux::netlink as netlink; +use mnl::linux::rtnetlink; + +extern { + // const char *inet_ntop(int af, const void *src, + // char *dst, socklen_t size); + fn inet_ntop(af: c_int, src: *const c_void, dst: *mut c_char, size: socklen_t) -> *const c_char; +} +pub const INET_ADDRSTRLEN: usize = 16; +pub const INET6_ADDRSTRLEN: usize = 46; + +trait AddrFamily { + fn family(&self) -> c_int; +} +impl AddrFamily for libc::in_addr { + fn family(&self) -> c_int { libc::AF_INET } +} +impl AddrFamily for libc::in6_addr { + fn family(&self) -> c_int { libc::AF_INET6 } +} + +fn _inet_ntoa(addr: &T) -> String { + let mut buf = [0u8; INET6_ADDRSTRLEN]; + unsafe { + let rs = inet_ntop(addr.family(), addr as *const _ as *const c_void, + buf.as_mut_ptr() as *mut c_char, INET6_ADDRSTRLEN as socklen_t); + CStr::from_ptr(rs).to_string_lossy().into_owned() + } +} + +macro_rules! println_stderr( + ($($arg:tt)*) => { { + let r = writeln!(&mut ::std::io::stderr(), $($arg)*); + r.expect("failed printing to stderr"); + } } +); + +fn attributes_show_ip(tb: &[Option<&mnl::Attr>]) { + tb[rtnetlink::RTA_TABLE as usize] + .map(|attr| print!("table={} ", attr.u32())); + tb[rtnetlink::RTA_DST as usize] + .map(|attr| print!("dst={} ", _inet_ntoa::(attr.payload()))); + tb[rtnetlink::RTA_SRC as usize] + .map(|attr| print!("src={} ", _inet_ntoa::(attr.payload()))); + tb[rtnetlink::RTA_OIF as usize] + .map(|attr| print!("oif={} ", attr.u32())); + tb[rtnetlink::RTA_FLOW as usize] + .map(|attr| print!("flow={} ", attr.u32())); + tb[rtnetlink::RTA_PREFSRC as usize] + .map(|attr| print!("prefsrc={} ", _inet_ntoa::(attr.payload()))); + tb[rtnetlink::RTA_GATEWAY as usize] + .map(|attr| print!("gw={} ", _inet_ntoa::(attr.payload()))); + tb[rtnetlink::RTA_PRIORITY as usize] + .map(|attr| print!("prio={} ", attr.u32())); + tb[rtnetlink::RTA_METRICS as usize] + .map(|attr| { + let mut tbx: [Option<&mnl::Attr>; rtnetlink::RTAX_MAX as usize + 1] + = [None; rtnetlink::RTAX_MAX as usize + 1]; + let _ = attr.parse_nested2(Box::new(move |attr| { + if let Err(_) = attr.type_valid(rtnetlink::RTAX_MAX as u16) { + return mnl::CbRet::OK; + } + + if let Err(errno) = attr.validate(mnl::AttrDataType::U32) { + println_stderr!("mnl_attr_validate: {}", errno); + return mnl::CbRet::ERROR; + } + tbx[attr.atype() as usize] = Some(attr); + mnl::CbRet::OK + })); + for i in 0..rtnetlink::RTAX_MAX as usize { + tbx[i].map(|attr| print!("metrics[{}]={} ", i, attr.u32())); + } + }); +} + +fn data_ipv4_attr_cb<'a, 'b>(tb: &'b mut [Option<&'a mnl::Attr>]) -> Box mnl::CbRet + 'b>{ + Box::new(move |attr: &'a mnl::Attr| { + // skip unsupported attribute in user-space + if let Err(_) = attr.type_valid(rtnetlink::RTA_MAX) { + return mnl::CbRet::OK; + } + + let atype = attr.atype(); + match atype { + n if (n == rtnetlink::RTA_TABLE || + n == rtnetlink::RTA_DST || + n == rtnetlink::RTA_SRC || + n == rtnetlink::RTA_DST || + n == rtnetlink::RTA_SRC || + n == rtnetlink::RTA_OIF || + n == rtnetlink::RTA_FLOW || + n == rtnetlink::RTA_PREFSRC || + n == rtnetlink::RTA_GATEWAY || + n == rtnetlink::RTA_PRIORITY) => { + if let Err(errno) = attr.validate(mnl::AttrDataType::U32) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if n == rtnetlink::RTA_METRICS => { + if let Err(errno) = attr.validate(mnl::AttrDataType::NESTED) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + _ => {}, + } + tb[atype as usize] = Some(attr); + mnl::CbRet::OK + }) +} + +fn data_ipv6_attr_cb<'a, 'b>(tb: &'b mut [Option<&'a mnl::Attr>]) -> Box mnl::CbRet + 'b>{ + Box::new(move |attr: &'a mnl::Attr| { + // skip unsupported attribute in user-space + if let Err(_) = attr.type_valid(rtnetlink::RTA_MAX) { + return mnl::CbRet::OK; + } + + let atype = attr.atype(); + match atype { + n if (n == rtnetlink::RTA_TABLE || + n == rtnetlink::RTA_OIF || + n == rtnetlink::RTA_FLOW || + n == rtnetlink::RTA_PRIORITY) => { + if let Err(errno) = attr.validate(mnl::AttrDataType::U32) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if (n == rtnetlink::RTA_DST || + n == rtnetlink::RTA_SRC || + n == rtnetlink::RTA_PREFSRC || + n == rtnetlink::RTA_GATEWAY) => { + if let Err(errno) = attr.validate2(mnl::AttrDataType::BINARY, size_of::()) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if n == rtnetlink::RTA_METRICS => { + if let Err(errno) = attr.validate(mnl::AttrDataType::NESTED) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + _ => {}, + } + tb[atype as usize] = Some(attr); + mnl::CbRet::OK + }) +} + +// fn data_cb<'a>(nlh: mnl::Nlmsg, _: &mut Option) -> mnl::CbRet { +fn data_cb<'a>() -> Box) -> mnl::CbRet> { + Box::new(move |nlh: mnl::Nlmsg<'a>| { + let rm = nlh.payload::(); + + // protocol family = AF_INET | AF_INET6 // + print!("family={} ", rm.rtm_family); + + // destination CIDR, eg. 24 or 32 for IPv4 + print!("dst_len={} ", rm.rtm_dst_len); + + // source CIDR + print!("src_len={} ", rm.rtm_src_len); + + // type of service (TOS), eg. 0 + print!("tos={} ", rm.rtm_tos); + + // table id: + // RT_TABLE_UNSPEC = 0 + // + // ... user defined values ... + // + // RT_TABLE_COMPAT = 252 + // RT_TABLE_DEFAULT = 253 + // RT_TABLE_MAIN = 254 + // RT_TABLE_LOCAL = 255 + // RT_TABLE_MAX = 0xFFFFFFFF + // + // Synonimous attribute: RTA_TABLE. + print!("table={} ", rm.rtm_table); + + // type: + // RTN_UNSPEC = 0 + // RTN_UNICAST = 1 + // RTN_LOCAL = 2 + // RTN_BROADCAST = 3 + // RTN_ANYCAST = 4 + // RTN_MULTICAST = 5 + // RTN_BLACKHOLE = 6 + // RTN_UNREACHABLE = 7 + // RTN_PROHIBIT = 8 + // RTN_THROW = 9 + // RTN_NAT = 10 + // RTN_XRESOLVE = 11 + // __RTN_MAX = 12 + print!("type={} ", rm.rtm_type); + + // scope: + // RT_SCOPE_UNIVERSE = 0 : everywhere in the universe + // + // ... user defined values ... + // + // RT_SCOPE_SITE = 200 + // RT_SCOPE_LINK = 253 : destination attached to link + // RT_SCOPE_HOST = 254 : local address + // RT_SCOPE_NOWHERE = 255 : not existing destination + print!("scope={} ", rm.rtm_scope); + + // protocol: + // RTPROT_UNSPEC = 0 + // RTPROT_REDIRECT = 1 + // RTPROT_KERNEL = 2 : route installed by kernel + // RTPROT_BOOT = 3 : route installed during boot + // RTPROT_STATIC = 4 : route installed by administrator + // + // Values >= RTPROT_STATIC are not interpreted by kernel, they are + // just user-defined. + print!("proto={} ", rm.rtm_protocol); + + // flags: + // RTM_F_NOTIFY = 0x100: notify user of route change + // RTM_F_CLONED = 0x200: this route is cloned + // RTM_F_EQUALIZE = 0x400: Multipath equalizer: NI + // RTM_F_PREFIX = 0x800: Prefix addresses + print!("flags={:x} ", rm.rtm_flags); + + let mut tb: [Option<&'a mnl::Attr>; rtnetlink::RTA_MAX as usize + 1] + = [None; rtnetlink::RTA_MAX as usize + 1]; + match rm.rtm_family as c_int { + libc::AF_INET => { + let _ = nlh.parse2(size_of::(), data_ipv4_attr_cb(&mut tb)); + attributes_show_ip::(&tb); + }, + libc::AF_INET6 => { + let _ = nlh.parse2(size_of::(), data_ipv6_attr_cb(&mut tb)); + attributes_show_ip::(&tb); + }, + _ => unreachable!() + } + + println!(""); + mnl::CbRet::OK + }) +} + +fn main() { + let args: Vec<_> = env::args().collect(); + if args.len() != 2 { + panic!("Usage: {} ", args[0]); + } + + let nl = mnl::Socket::open(netlink::Family::ROUTE) + .unwrap_or_else(|errno| panic!("mnl_socket_open: {}", errno)); + nl.bind(0, mnl::SOCKET_AUTOPID) + .unwrap_or_else(|errno| panic!("mnl_socket_bind: {}", errno)); + let portid = nl.portid(); + + let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; + let seq = time::now().to_timespec().sec as u32; + { + let mut nlh = mnl::Nlmsg::new(&mut buf); + *nlh.nlmsg_type = rtnetlink::RTM_GETROUTE; + *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; + *nlh.nlmsg_seq = seq; + let rtm = nlh.put_sized_header::(); + if args[1] == "inet" { + rtm.rtm_family = libc::AF_INET as u8; + } else if args[1] == "inet6" { + rtm.rtm_family = libc::AF_INET6 as u8; + } + nl.send_nlmsg(&nlh) + .unwrap_or_else(|errno| panic!("mnl_socket_sendto: {}", errno)); + } + + loop { + let nrecv = nl.recvfrom(&mut buf) + .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); + + // if mnl::cb_run(&buf[0..nrecv], seq, portid, Some(data_cb), &mut None) + if mnl::cb_run3(&buf[0..nrecv], seq, portid, Some(data_cb())) + .unwrap_or_else(|errno| panic!("mnl_cb_run: {}", errno)) + == mnl::CbRet::STOP { + break; + } + } + let _ = nl.close(); +} diff --git a/src/lib.rs b/src/lib.rs index 9cde1a1..992b765 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ // no effect? #![link(name = "mnl")] use std::io; -use std::mem::{ size_of, size_of_val, zeroed }; +use std::mem::{ size_of, size_of_val, zeroed, forget }; use std::os::unix::io::{ RawFd, AsRawFd }; use std::ffi::{ CString, CStr }; use std::fmt; @@ -985,6 +985,11 @@ impl <'a> Nlmsg <'a> { cvt_cbret!(mnl_attr_parse(self.as_raw_ref(), offset as c_uint, attr_parse_cb::, pdata)) } + pub fn parse2<'b, 'c>(&self, offset: usize, cb: Box CbRet + 'c>) -> io::Result<(CbRet)> { + cvt_cbret!(mnl_attr_parse(self.as_raw_ref(), offset as c_uint, attr_parse_cb2, + Box::into_raw(Box::new(cb)) as *mut c_void)) + } + pub fn attrs(&'a self, offset: usize) -> Box + 'a> { Box::new(AttrIterator { attr: self.payload_offset::(offset), tail: self.payload_tail::() as *const _ as uintptr_t }) @@ -1306,6 +1311,10 @@ impl <'a> Attr { cvt_cbret!(mnl_attr_parse_nested(self, attr_parse_cb::, pdata)) } + pub fn parse_nested2<'b>(&self, cb: Box CbRet + 'b>) -> io::Result<(CbRet)> { + cvt_cbret!(mnl_attr_parse_nested(self, attr_parse_cb2, Box::into_raw(Box::new(cb)) as *mut c_void)) + } + pub fn nesteds(&'a self) -> Box + 'a> { Box::new(AttrIterator { attr: self.payload::(), tail: self.payload::() as *const _ as uintptr_t @@ -1321,6 +1330,15 @@ extern fn attr_parse_cb(attr: *const netlink::Nlattr, data: *mut c_vo } } +extern fn attr_parse_cb2(attr: *const netlink::Nlattr, data: *mut c_void) -> c_int { + unsafe { + let mut cb = Box::from_raw(data as *mut Box CbRet>); + let rc = (cb)(attr.as_ref().unwrap()) as c_int; + forget(cb); + rc + } +} + /// parse attributes in payload of Netlink message /// /// # Arguments @@ -1358,6 +1376,19 @@ extern fn nlmsg_parse_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_ } } +extern fn nlmsg_parse_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { + unsafe { + let mut op = Box::from_raw(data as *mut (Option CbRet>>, + Option CbRet>>)); + let mut rc = CbRet::OK as c_int; + if let Some(ref mut cb) = op.0.as_mut() { + rc = cb(Nlmsg::from_raw(nlh)) as c_int; + } + forget(op); + rc + } +} + extern fn nlmsg_ctl_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { unsafe { let arg = &mut *(data as *mut CbData); @@ -1368,6 +1399,16 @@ extern fn nlmsg_ctl_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_vo } } +extern fn nlmsg_ctl_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { + unsafe { + let mut op = Box::from_raw(data as *mut (Option CbRet>>, + Option CbRet>>)); + let rc = op.1.as_mut().unwrap()(Nlmsg::from_raw(nlh)) as c_int; + forget(op); + rc + } +} + pub fn cb_run<'a, 'b, T: 'a + 'b + ?Sized>(buf: &[u8], seq: u32, portid: u32, cb_data: Option>, data: &'b mut T) -> io::Result<(CbRet)> { @@ -1377,6 +1418,14 @@ pub fn cb_run<'a, 'b, T: 'a + 'b + ?Sized>(buf: &[u8], seq: u32, portid: u32, seq, portid, nlmsg_parse_cb::, argp)) } +pub fn cb_run3<'a, 'b>(buf: &[u8], seq: u32, portid: u32, + cb_data: Option) -> CbRet + 'b>>) + -> io::Result<(CbRet)> { + cvt_cbret!(mnl_cb_run(buf.as_ptr() as *const c_void, buf.len() as size_t, + seq, portid, nlmsg_parse_cb2, + Box::into_raw(Box::new((cb_data, None:: CbRet>>))) as *mut c_void)) +} + /// callback runqueue for netlink messages /// # Arguments /// * `buf` buffer that contains the netlink messages @@ -1417,3 +1466,18 @@ pub fn cb_run2<'a, 'b, T: 'a + 'b + ?Sized>(buf: &[u8], seq: u32, portid: u32, seq, portid, nlmsg_parse_cb::, argp, cb_ctl_array.as_ptr() as *const CbT, netlink::NLMSG_MIN_TYPE as c_uint)) } + +pub fn cb_run4<'a, 'b>(buf: &[u8], seq: u32, portid: u32, + cb_data: Option) -> CbRet + 'b>>, + cb_ctl: Box) -> CbRet + 'b>, ctltypes: &[u16]) + -> io::Result<(CbRet)> { + let mut cb_ctl_array: [CbT; netlink::NLMSG_MIN_TYPE as usize - 1] = unsafe { zeroed() }; + for i in ctltypes.into_iter() { + cb_ctl_array[*i as usize] = nlmsg_ctl_cb2; + } + + let data = Box::into_raw(Box::new((cb_data, Some(cb_ctl)))) as *mut c_void; + cvt_cbret!(mnl_cb_run2(buf.as_ptr() as *const c_void, buf.len() as size_t, + seq, portid, nlmsg_parse_cb2, data, + cb_ctl_array.as_ptr() as *const CbT, netlink::NLMSG_MIN_TYPE as c_uint)) +} diff --git a/tests/lib.rs b/tests/lib.rs index 48e79bf..77b3e31 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -851,6 +851,45 @@ fn nlmsg_parse() { } } +#[test] +fn nlmsg_parse_2() { + let mut buf = vec![0u8; 512]; + { + let mut nlh = mnl::Nlmsg::new(&mut buf); + nlh.put_u8(1, 0x11); + nlh.put_u8(2, 0x12); + nlh.put_u8(3, 0x13); + nlh.put_u8(4, 0x14); + let mut data = 1; + assert!(nlh.parse2(0, Box::new(|attr| { + if attr.nla_type as u8 != data { + return mnl::CbRet::ERROR; + } + if attr.u8() != 0x10 + data { + return mnl::CbRet::ERROR; + } + data += 1; + mnl::CbRet::OK + })).unwrap() == mnl::CbRet::OK); + } + { + let mut nlh = mnl::Nlmsg::new(&mut buf); + nlh.put_u8(0, 0x0); + let mut data = 1; + assert!(nlh.parse2(0, Box::new(|attr| { + if attr.nla_type as u8 != data { + return mnl::CbRet::ERROR; + } + if attr.u8() != 0x10 + data { + return mnl::CbRet::ERROR; + } + data += 1; + mnl::CbRet::OK + })).is_err()); + } +} + + #[test] fn nlmsg_attrs() { let mut buf = vec![0u8; 512]; From ee1597a99bf3143c65b4943a2f05d0cc552bd563 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Thu, 18 May 2017 11:55:08 +0900 Subject: [PATCH 03/27] [mnl] fix multiple nlmsg printing --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 992b765..e0e23d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -693,7 +693,7 @@ impl <'a> Nlmsg <'a> { unsafe { let f = libc::fdopen(fd.as_raw_fd(), mode.as_ptr()); mnl_nlmsg_fprintf(f, self.as_raw_ref() as *const _ as *const c_void, - *self.nlmsg_len as size_t, extra_header_size as size_t) + self.buf.len() as size_t, extra_header_size as size_t) } } From 803f4dc9a2b93771c87741f839ce5f827345a96d Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 22 May 2017 10:20:47 +0900 Subject: [PATCH 04/27] [mnl] prepare for more safe methods --- src/nlmsg_ext.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/nlmsg_ext.c b/src/nlmsg_ext.c index d93470c..c7f24fe 100644 --- a/src/nlmsg_ext.c +++ b/src/nlmsg_ext.c @@ -1,5 +1,22 @@ #include #include +#include + +struct nlmsghdr *mnl_nlmsg_put_header_check(void *buf, size_t buflen) +{ + if (MNL_NLMSG_HDRLEN < buflen) + return NULL; + + return mnl_nlmsg_put_header(buf); +} + +void *mnl_nlmsg_put_extra_header_check(struct nlmsghdr *nlh, size_t buflen, size_t size) +{ + if (nlh->nlmsg_len + MNL_ALIGN(size) > buflen) + return NULL; + + return mnl_nlmsg_put_extra_header(nlh, size); +} struct mnl_nlmsg_batch { /* the buffer that is used to store the batch. */ From c52d7a52e614fc3095aebe83bf5a110ba47e2e8e Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 22 May 2017 10:22:38 +0900 Subject: [PATCH 05/27] [mnl] implement Iterator for Nlmsg But I'm not sure its lifetime is correct. --- src/lib.rs | 37 ++++++++++++++++++++++--------------- tests/lib.rs | 5 +++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e0e23d0..411a795 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -445,6 +445,7 @@ impl AsRawFd for Socket { pub struct Nlmsg <'a> { buf: &'a mut [u8], + remaining: isize, pub nlmsg_len: &'a mut u32, pub nlmsg_type: &'a mut u16, pub nlmsg_flags: &'a mut u16, @@ -487,11 +488,13 @@ impl <'a> Nlmsg <'a> { unsafe { mnl_nlmsg_get_payload_len(self.as_raw_ref()) } } - pub fn from_bytes(buf: &mut [u8]) -> Nlmsg { + pub fn from_bytes(buf: &'a mut [u8]) -> Self { // XXX: check buf len > sizeof(Nlmsg) + let buflen = buf.len() as isize; let p = buf.as_mut_ptr(); let nlh = Nlmsg { buf: buf, + remaining: buflen, nlmsg_len: unsafe { (p as *mut u32).offset(0).as_mut().unwrap() }, nlmsg_type: unsafe { (p as *mut u16).offset(2).as_mut().unwrap() }, nlmsg_flags: unsafe { (p as *mut u16).offset(3).as_mut().unwrap() }, @@ -511,7 +514,7 @@ impl <'a> Nlmsg <'a> { /// header in the memory buffer passed as parameter. This function also /// initializes the nlmsg_len field to the size of the Netlink header. This /// function returns a Netlink header structure. - pub fn new(buf: &mut [u8]) -> Nlmsg { + pub fn new(buf: &'a mut [u8]) -> Self { let mut nlh = Self::from_bytes(buf); nlh.put_header(); nlh @@ -559,13 +562,12 @@ impl <'a> Nlmsg <'a> { unsafe { &mut(*(mnl_nlmsg_put_extra_header(self.as_raw_mut(), size_of::()) as *mut T)) } } - pub fn ok(&self, len: usize) -> bool { + pub fn ok(&self, len: isize) -> bool { unsafe { mnl_nlmsg_ok(self.as_raw_ref(), len as c_int) } } - pub fn next(&mut self, len: isize) -> (Nlmsg, isize) { + pub fn raw_next<'b: 'a>(&'b mut self, len: isize) -> (Self, isize) { let mut rest = len as c_int; - // let nlh = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut rest)) }; let _ = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut rest)) }; let u = self.buf.len() - rest as usize; (Self::from_bytes(&mut self.buf[u..]), rest as isize) @@ -996,26 +998,31 @@ impl <'a> Nlmsg <'a> { } } +impl <'a> Iterator for Nlmsg<'a> { + type Item = Self; + + fn next(&mut self) -> Option { + if ! unsafe { mnl_nlmsg_ok(self.as_raw_ref(), self.remaining as c_int) } { + return None; + } + let nlh = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut (self.remaining as c_int))) }; + Some(Self::from_raw(nlh)) + } +} + struct AttrIterator<'a> { attr: &'a Attr, tail: uintptr_t, } -impl <'a> AttrIterator <'a> { - fn ok(&self) -> bool { - self.attr.ok( - self.tail - self.attr as *const _ as uintptr_t - ) - } -} - -impl <'a> Iterator for AttrIterator <'a> { +impl <'a> Iterator for AttrIterator<'a> { type Item = &'a Attr; fn next(&mut self) -> Option<&'a Attr> { - if !self.ok() { + if !self.attr.ok(self.tail - self.attr as *const _ as uintptr_t) { return None; } + let curr = self.attr; self.attr = curr.next(); Some(curr) diff --git a/tests/lib.rs b/tests/lib.rs index 77b3e31..0c7bb9d 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -150,8 +150,9 @@ fn nlmsg_next_header() { let mut buf: Vec = repeat(0u8).take(512).collect(); { let mut nlh = mnl::Nlmsg::new(&mut buf); - let (next_nlh, rest) = nlh.next(512); - assert!(rest == 512 - hdrlen as isize); + // let (next_nlh, rest) = nlh.next(512); + let next_nlh = nlh.next().unwrap(); + // assert!(rest == 512 - hdrlen as isize); assert!(*next_nlh.nlmsg_len == 0); *next_nlh.nlmsg_len = 0x11111111; } From be2130bcfb5762fe75f98b924c3c1dba5db5532f Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 22 May 2017 10:25:15 +0900 Subject: [PATCH 06/27] [examples] add more for closure --- examples/genl-family-get2.rs | 1 + examples/genl/genl-family-get2.rs | 226 ++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 120000 examples/genl-family-get2.rs create mode 100644 examples/genl/genl-family-get2.rs diff --git a/examples/genl-family-get2.rs b/examples/genl-family-get2.rs new file mode 120000 index 0000000..074a4c4 --- /dev/null +++ b/examples/genl-family-get2.rs @@ -0,0 +1 @@ +genl/genl-family-get2.rs \ No newline at end of file diff --git a/examples/genl/genl-family-get2.rs b/examples/genl/genl-family-get2.rs new file mode 100644 index 0000000..3e2a6d7 --- /dev/null +++ b/examples/genl/genl-family-get2.rs @@ -0,0 +1,226 @@ +use std::env; +use std::io::Write; +use std::mem::size_of; + +extern crate libc; +extern crate time; +extern crate crslmnl as mnl; + +use mnl::linux::netlink as netlink; +use mnl::linux::genetlink as genl; + + +macro_rules! println_stderr( + ($($arg:tt)*) => { { + let r = writeln!(&mut ::std::io::stderr(), $($arg)*); + r.expect("failed printing to stderr"); + } } +); + +fn parse_mc_grps_cb<'a, 'b>(tb: &'b mut [Option<&'a mnl::Attr>]) -> Box mnl::CbRet + 'b> { + Box::new(move |attr: &'a mnl::Attr| { + // skip unsupported attribute in user-space + if let Err(_) = attr.type_valid(genl::CTRL_ATTR_MCAST_GRP_MAX as u16) { + return mnl::CbRet::OK; + } + + let atype = attr.atype(); + match atype { + n if n == genl::CtrlAttrMcastGrp::ID as u16 => { + if let Err(errno) = attr.validate(mnl::AttrDataType::U32) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if n == genl::CtrlAttrMcastGrp::NAME as u16 => { + if let Err(errno) = attr.validate(mnl::AttrDataType::STRING) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + _ => {}, + } + tb[atype as usize] = Some(attr); + mnl::CbRet::OK + }) +} + +fn parse_genl_mc_grps(nested: &mnl::Attr) { + for pos in nested.nesteds() { + let mut tb: [Option<&mnl::Attr>; genl::CTRL_ATTR_MCAST_GRP_MAX as usize + 1] + = [None; genl::CTRL_ATTR_MCAST_GRP_MAX as usize + 1]; + + let _ = pos.parse_nested2(parse_mc_grps_cb(&mut tb)); + + tb[genl::CtrlAttrMcastGrp::ID as usize] + .map(|attr| print!("id-0x{:x} ", attr.u32())); + tb[genl::CtrlAttrMcastGrp::NAME as usize] + .map(|attr| print!("name: {} ", attr.str())); + println!(""); + } +} + +fn parse_genl_family_ops<'a>(nested: &mnl::Attr) { + for pos in nested.nesteds() { + let mut tb: [Option<&'a mnl::Attr>; genl::CTRL_ATTR_OP_MAX as usize + 1] + = [None; genl::CTRL_ATTR_OP_MAX as usize + 1]; + + let _ = pos.parse_nested2(Box::new(|attr: &'a mnl::Attr| { + if let Err(_) = attr.type_valid(genl::CTRL_ATTR_OP_MAX) { + return mnl::CbRet::OK; + } + + let atype = attr.atype(); + match atype { + n if (n == genl::CtrlAttrOp::ID as u16 || + n == genl::CtrlAttrOp::FLAGS as u16) => { + if let Err(errno) = attr.validate(mnl::AttrDataType::U32) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if n == genl::CTRL_ATTR_OP_MAX => {}, + _ => { + return mnl::CbRet::OK; + }, + } + + tb[atype as usize] = Some(attr); + return mnl::CbRet::OK; + })); + + tb[genl::CtrlAttrOp::ID as usize] + .map(|attr| print!("id-0x{:x} ", attr.u32())); + tb[genl::CtrlAttrOp::FLAGS as usize] + .map(|attr| print!("flags 0x{:08x}", attr.u32())); + println!(""); + } +} + +fn data_attr_cb<'a, 'b>(tb: &'b mut [Option<&'a mnl::Attr>]) + -> Box mnl::CbRet + 'b> +{ + Box::new(move |attr: &'a mnl::Attr| { + if let Err(_) = attr.type_valid(genl::CTRL_ATTR_MAX) { + return mnl::CbRet::OK; + } + + let atype = attr.atype(); + match atype { + n if n == genl::CtrlAttr::FAMILY_NAME as u16 => { + if let Err(errno) = attr.validate(mnl::AttrDataType::STRING) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if n == genl::CtrlAttr::FAMILY_ID as u16 => { + if let Err(errno) = attr.validate(mnl::AttrDataType::U16) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if (n == genl::CtrlAttr::VERSION as u16 || + n == genl::CtrlAttr::HDRSIZE as u16 || + n == genl::CtrlAttr::MAXATTR as u16) => { + if let Err(errno) = attr.validate(mnl::AttrDataType::U32) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + n if (n == genl::CtrlAttr::OPS as u16 || + n == genl::CtrlAttr::MCAST_GROUPS as u16) => { + if let Err(errno) = attr.validate(mnl::AttrDataType::NESTED) { + println_stderr!("mnl_attr_validate - {}: {}", atype, errno); + return mnl::CbRet::ERROR; + } + }, + _ => {}, + } + + tb[atype as usize] = Some(attr); + return mnl::CbRet::OK; + }) +} + +fn data_cb() -> Box mnl::CbRet> { + Box::new(|nlh: mnl::Nlmsg| { + let mut tb: [Option<&mnl::Attr>; genl::CTRL_ATTR_MAX as usize + 1] + = [None; genl::CTRL_ATTR_MAX as usize + 1]; + + let _ = nlh.parse2(size_of::(), data_attr_cb(&mut tb)); + + tb[genl::CtrlAttr::FAMILY_NAME as usize] + .map(|attr| print!("name={}\t", attr.str())); + tb[genl::CtrlAttr::FAMILY_ID as usize] + .map(|attr| print!("id={}\t", attr.u16())); + tb[genl::CtrlAttr::VERSION as usize] + .map(|attr| print!("version={}\t", attr.u32())); + tb[genl::CtrlAttr::HDRSIZE as usize] + .map(|attr| print!("hdrsize={}\t", attr.u32())); + tb[genl::CtrlAttr::MAXATTR as usize] + .map(|attr| print!("maxattr={}\t", attr.u32())); + println!(""); + + tb[genl::CtrlAttr::OPS as usize] + .map(|attr| { + println!("ops:"); + parse_genl_family_ops(attr); + }); + tb[genl::CtrlAttr::MCAST_GROUPS as usize] + .map(|attr| { + println!("grps:"); + parse_genl_mc_grps(attr); + }); + println!(""); + + return mnl::CbRet::OK; + }) +} + +fn main() { + let args: Vec<_> = env::args().collect(); + if args.len() > 2 { + panic!("{} [family name]", args[0]); + } + + let nl = mnl::Socket::open(netlink::Family::GENERIC) + .unwrap_or_else(|errno| panic!("mnl_socket_open: {}", errno)); + nl.bind(0, mnl::SOCKET_AUTOPID) + .unwrap_or_else(|errno| panic!("mnl_socket_bind: {}", errno)); + let portid = nl.portid(); + + let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; + let seq = time::now().to_timespec().sec as u32; + { + let mut nlh = mnl::Nlmsg::new(&mut buf); + *nlh.nlmsg_type = genl::GENL_ID_CTRL; + *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; + *nlh.nlmsg_seq = seq; + + let genl = nlh.put_sized_header::(); + genl.cmd = genl::CtrlCmd::GETFAMILY as u8; + genl.version = 1; + + nlh.put_u16(genl::CtrlAttr::FAMILY_ID as u16, genl::GENL_ID_CTRL); + if args.len() >= 2 { + nlh.put_strz(genl::CtrlAttr::FAMILY_NAME as u16, &args[1]); + } else { + *nlh.nlmsg_flags |= netlink::NLM_F_DUMP; + } + + nl.send_nlmsg(&nlh) + .unwrap_or_else(|errno| panic!("mnl_socket_sendto: {}", errno)); + } + + loop { + let nrecv = nl.recvfrom(&mut buf) + .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); + + if mnl::cb_run3(&buf[0..nrecv], seq, portid, Some(data_cb())) + .unwrap_or_else(|errno| panic!("mnl_cb_run: {}", errno)) + == mnl::CbRet::STOP { + break; + } + } + let _ = nl.close(); +} From ecd11b6954c69a8c6a19f8365b5b725091c47d0a Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Wed, 24 May 2017 15:52:56 +0900 Subject: [PATCH 07/27] mnl: review nlmsg cb_run update lifetime and ctl cb array, control callback handling. --- examples/netfilter/nfct-create-batch.rs | 22 +++---- examples/netfilter/nfct-create-batch2.rs | 21 +++--- examples/rtnl/rtnl-route-dump2.rs | 7 +- src/lib.rs | 82 +++++++++++------------- tests/lib.rs | 72 +++++++++++++++++++++ 5 files changed, 132 insertions(+), 72 deletions(-) diff --git a/examples/netfilter/nfct-create-batch.rs b/examples/netfilter/nfct-create-batch.rs index aa97c07..be383f8 100644 --- a/examples/netfilter/nfct-create-batch.rs +++ b/examples/netfilter/nfct-create-batch.rs @@ -66,16 +66,11 @@ fn put_msg(nlh: &mut mnl::Nlmsg, i: u16, seq: u32) { nlh.put_u32(nfct::CTA_TIMEOUT, u32::to_be(1000)); } -fn ctl_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { - match *nlh.nlmsg_type { - netlink::NLMSG_ERROR => { - let err = nlh.payload::(); - if err.error != 0 { - println!("message with seq {} has failed: {}", - nlh.nlmsg_seq, io::Error::from_raw_os_error(-err.error)); - } - }, - _ => {}, +fn error_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { + let err = nlh.payload::(); + if err.error != 0 { + println!("message with seq {} has failed: {}", + nlh.nlmsg_seq, io::Error::from_raw_os_error(-err.error)); } mnl::CbRet::OK } @@ -96,7 +91,9 @@ fn send_batch(nl: &mut mnl::Socket, b: &mut mnl::NlmsgBatch, portid: u32) { let mut events = mio::Events::with_capacity(256); let mut rcv_buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; - + let ctl_cbs = [None, + None, // NLMSG_NOOP + Some(error_cb as mnl::Cb),]; // NLMSG_ERROR loop { timer.settime( 0, @@ -119,8 +116,7 @@ fn send_batch(nl: &mut mnl::Socket, b: &mut mnl::NlmsgBatch, portid: u32) { let nrecv = nl.recvfrom(&mut rcv_buf) .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); let rc = mnl::cb_run2(&rcv_buf[0..nrecv], 0, portid, - None, &mut 0, - ctl_cb, &[netlink::NLMSG_ERROR]) + None, &mut 0, &ctl_cbs[..]) .unwrap_or_else(|errno| panic!("mnl_cb_run2: {}", errno)); if rc == mnl::CbRet::STOP { return; diff --git a/examples/netfilter/nfct-create-batch2.rs b/examples/netfilter/nfct-create-batch2.rs index b8a1c78..8a36025 100644 --- a/examples/netfilter/nfct-create-batch2.rs +++ b/examples/netfilter/nfct-create-batch2.rs @@ -63,16 +63,11 @@ fn put_msg(nlh: &mut mnl::Nlmsg, i: u16, seq: u32) { nlh.put_u32(nfct::CTA_TIMEOUT, u32::to_be(1000)); } -fn ctl_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { - match *nlh.nlmsg_type { - netlink::NLMSG_ERROR => { - let err = nlh.payload::(); - if err.error != 0 { - println!("message with seq {} has failed: {}", - nlh.nlmsg_seq, io::Error::from_raw_os_error(-err.error)); - } - }, - _ => {}, +fn error_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { + let err = nlh.payload::(); + if err.error != 0 { + println!("message with seq {} has failed: {}", + nlh.nlmsg_seq, io::Error::from_raw_os_error(-err.error)); } mnl::CbRet::OK } @@ -90,6 +85,9 @@ fn send_batch(nl: &mut mnl::Socket, b: &mut mnl::NlmsgBatch, portid: u32) { let mut events: [epoll::Event; 1] = unsafe { zeroed() }; let mut rcv_buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; + let ctl_cbs = [None, + None, // NLMSG_NOOP + Some(error_cb as mnl::Cb),]; // NLMSG_ERROR loop { let nevents = epoll.wait(&mut events[..], 1) .unwrap_or_else(|errno| panic!("epoll_wait: {}", errno)); @@ -109,8 +107,7 @@ fn send_batch(nl: &mut mnl::Socket, b: &mut mnl::NlmsgBatch, portid: u32) { let nrecv = nl.recvfrom(&mut rcv_buf) .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); let rc = mnl::cb_run2(&rcv_buf[0..nrecv], 0, portid, - None, &mut 0, - ctl_cb, &[netlink::NLMSG_ERROR]) + None, &mut 0, &ctl_cbs[..]) .unwrap_or_else(|errno| panic!("mnl_cb_run2: {}", errno)); if rc == mnl::CbRet::STOP { return; diff --git a/examples/rtnl/rtnl-route-dump2.rs b/examples/rtnl/rtnl-route-dump2.rs index 0d65aa4..e35159d 100644 --- a/examples/rtnl/rtnl-route-dump2.rs +++ b/examples/rtnl/rtnl-route-dump2.rs @@ -162,8 +162,9 @@ fn data_ipv6_attr_cb<'a, 'b>(tb: &'b mut [Option<&'a mnl::Attr>]) -> Box(nlh: mnl::Nlmsg, _: &mut Option) -> mnl::CbRet { -fn data_cb<'a>() -> Box) -> mnl::CbRet> { - Box::new(move |nlh: mnl::Nlmsg<'a>| { +// fn data_cb<'a>() -> Box) -> mnl::CbRet> { +fn data_cb() -> Box mnl::CbRet> { + Box::new(move |nlh: mnl::Nlmsg| { let rm = nlh.payload::(); // protocol family = AF_INET | AF_INET6 // @@ -237,7 +238,7 @@ fn data_cb<'a>() -> Box) -> mnl::CbRet> { // RTM_F_PREFIX = 0x800: Prefix addresses print!("flags={:x} ", rm.rtm_flags); - let mut tb: [Option<&'a mnl::Attr>; rtnetlink::RTA_MAX as usize + 1] + let mut tb: [Option<&mnl::Attr>; rtnetlink::RTA_MAX as usize + 1] = [None; rtnetlink::RTA_MAX as usize + 1]; match rm.rtm_family as c_int { libc::AF_INET => { diff --git a/src/lib.rs b/src/lib.rs index 411a795..8e707e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,10 +219,10 @@ pub enum CbRet { type CbT = extern "C" fn(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int; pub type Cb<'a, T: ?Sized> = fn(nlh: Nlmsg, data: &'a mut T) -> CbRet; -struct CbData <'a, 'b, T: 'a + 'b + ?Sized> { - cb: Option>, - ctl_cb: Option>, - data: &'b mut T, +struct CbData <'a, 'b: 'a, T: 'b + ?Sized> { + cb: Option>, + ctl_cbs: &'a [Option>], + data: &'a mut T, } @@ -1386,7 +1386,7 @@ extern fn nlmsg_parse_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_ extern fn nlmsg_parse_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { unsafe { let mut op = Box::from_raw(data as *mut (Option CbRet>>, - Option CbRet>>)); + &[Option CbRet>>])); let mut rc = CbRet::OK as c_int; if let Some(ref mut cb) = op.0.as_mut() { rc = cb(Nlmsg::from_raw(nlh)) as c_int; @@ -1399,7 +1399,7 @@ extern fn nlmsg_parse_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c extern fn nlmsg_ctl_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { unsafe { let arg = &mut *(data as *mut CbData); - if let Some(ctl_cb) = arg.ctl_cb { + if let Some(ctl_cb) = arg.ctl_cbs[(*nlh).nlmsg_type as usize] { return ctl_cb(Nlmsg::from_raw(nlh), arg.data) as c_int; } CbRet::OK as c_int // MNL_CB_OK @@ -1408,29 +1408,33 @@ extern fn nlmsg_ctl_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_vo extern fn nlmsg_ctl_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { unsafe { - let mut op = Box::from_raw(data as *mut (Option CbRet>>, - Option CbRet>>)); - let rc = op.1.as_mut().unwrap()(Nlmsg::from_raw(nlh)) as c_int; - forget(op); + let mut cbs = Box::from_raw(data as *mut (Option CbRet>>, + &mut [Option CbRet>>])); + let rc = match cbs.1[(*nlh).nlmsg_type as usize] { + Some(ref mut cb) => cb(Nlmsg::from_raw(nlh)) as c_int, + None => CbRet::OK as c_int, + }; + forget(cbs); rc } } -pub fn cb_run<'a, 'b, T: 'a + 'b + ?Sized>(buf: &[u8], seq: u32, portid: u32, - cb_data: Option>, data: &'b mut T) - -> io::Result<(CbRet)> { - let mut arg = CbData{ cb: cb_data, ctl_cb: None, data: data }; +pub fn cb_run<'a, T>(buf: &[u8], seq: u32, portid: u32, + cb_data: Option>, data: &mut T) + -> io::Result<(CbRet)> { + let nil = [None::>]; + let mut arg = CbData{ cb: cb_data, ctl_cbs: &nil, data: data }; let argp = &mut arg as *mut _ as *mut c_void; cvt_cbret!(mnl_cb_run(buf.as_ptr() as *const c_void, buf.len() as size_t, seq, portid, nlmsg_parse_cb::, argp)) } -pub fn cb_run3<'a, 'b>(buf: &[u8], seq: u32, portid: u32, - cb_data: Option) -> CbRet + 'b>>) - -> io::Result<(CbRet)> { +pub fn cb_run3(buf: &[u8], seq: u32, portid: u32, + cb_data: Option CbRet>>) + -> io::Result<(CbRet)> { cvt_cbret!(mnl_cb_run(buf.as_ptr() as *const c_void, buf.len() as size_t, seq, portid, nlmsg_parse_cb2, - Box::into_raw(Box::new((cb_data, None:: CbRet>>))) as *mut c_void)) + Box::into_raw(Box::new((cb_data, &[None:: CbRet>>]))) as *mut c_void)) } /// callback runqueue for netlink messages @@ -1454,37 +1458,27 @@ pub fn cb_run3<'a, 'b>(buf: &[u8], seq: u32, portid: u32, /// is set to ESRCH. If the sequence number is not the expected, errno is set /// to EPROTO. If the dump was interrupted, errno is set to EINTR and you should /// request a new fresh dump again. -pub fn cb_run2<'a, 'b, T: 'a + 'b + ?Sized>(buf: &[u8], seq: u32, portid: u32, - cb_data: Option>, data: &'b mut T, - cb_ctl: Cb<'a, T>, ctltypes: &[u16]) - -> io::Result<(CbRet)> { - - // XXX: can not assign NULL? - // let mut cb_ctl_array: [CbT; netlink::NLMSG_MIN_TYPE as usize] - // = [std::ptr::null() as CbT; netlink::NLMSG_MIN_TYPE as usize]; - let mut cb_ctl_array: [CbT; netlink::NLMSG_MIN_TYPE as usize - 1] = unsafe { zeroed() }; - - for i in ctltypes.into_iter() { - cb_ctl_array[*i as usize] = nlmsg_ctl_cb::; - } - let mut arg = CbData{ cb: cb_data, ctl_cb: Some(cb_ctl), data: data }; +pub fn cb_run2<'a, T: 'a>(buf: &[u8], seq: u32, portid: u32, + cb_data: Option>, data: &mut T, + ctl_cbs: &'a [Option>]) + -> io::Result<(CbRet)> { + let ctlen = ctl_cbs.len(); + let raw_ctl_cbs = vec![nlmsg_ctl_cb:: as CbT; ctlen]; + let mut arg = CbData{ cb: cb_data, ctl_cbs: ctl_cbs, data: data }; let argp = &mut arg as *mut _ as *mut c_void; cvt_cbret!(mnl_cb_run2(buf.as_ptr() as *const c_void, buf.len() as size_t, seq, portid, nlmsg_parse_cb::, argp, - cb_ctl_array.as_ptr() as *const CbT, netlink::NLMSG_MIN_TYPE as c_uint)) + raw_ctl_cbs.as_ptr() as *const CbT, ctlen as c_uint)) } -pub fn cb_run4<'a, 'b>(buf: &[u8], seq: u32, portid: u32, - cb_data: Option) -> CbRet + 'b>>, - cb_ctl: Box) -> CbRet + 'b>, ctltypes: &[u16]) - -> io::Result<(CbRet)> { - let mut cb_ctl_array: [CbT; netlink::NLMSG_MIN_TYPE as usize - 1] = unsafe { zeroed() }; - for i in ctltypes.into_iter() { - cb_ctl_array[*i as usize] = nlmsg_ctl_cb2; - } - - let data = Box::into_raw(Box::new((cb_data, Some(cb_ctl)))) as *mut c_void; +pub fn cb_run4(buf: &[u8], seq: u32, portid: u32, + cb_data: Option CbRet>>, + cb_ctl_array: &mut [Option CbRet>>]) + -> io::Result<(CbRet)> { + let ctlen = cb_ctl_array.len(); + let raw_ctl_cbs = vec![nlmsg_ctl_cb2 as CbT; ctlen]; + let data = Box::into_raw(Box::new((cb_data, cb_ctl_array))) as *mut c_void; cvt_cbret!(mnl_cb_run2(buf.as_ptr() as *const c_void, buf.len() as size_t, seq, portid, nlmsg_parse_cb2, data, - cb_ctl_array.as_ptr() as *const CbT, netlink::NLMSG_MIN_TYPE as c_uint)) + raw_ctl_cbs.as_ptr() as *const CbT, ctlen as c_uint)) } diff --git a/tests/lib.rs b/tests/lib.rs index 0c7bb9d..3c924f5 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1033,3 +1033,75 @@ fn nlmsg_batch_is_empty() { b.reset(); assert!(b.is_empty() == true); } + +// fn nlmsg_cb_ok<'a>() -> Box) -> mnl::CbRet> { +fn nlmsg_cb_ok() -> Box mnl::CbRet> { + Box::new(|_| mnl::CbRet::OK) +} + +// fn nlmsg_cb_stop<'a>() -> Box) -> mnl::CbRet> { +fn nlmsg_cb_stop() -> Box mnl::CbRet> { + Box::new(|_| mnl::CbRet::STOP) +} + +// fn nlmsg_cb_error<'a>() -> Box) -> mnl::CbRet> { +fn nlmsg_cb_error() -> Box mnl::CbRet> { + Box::new(|_| mnl::CbRet::ERROR) +} + +#[test] +fn nlmsg_cb_run4() { + let mut buf = vec![0u8; 512]; + let b = mnl::NlmsgBatch::start(&mut *buf, 512 / 2).unwrap(); + { + let mut nlh = b.current_nlmsg(); + nlh.put_header(); + *nlh.nlmsg_type = linux::netlink::NLMSG_NOOP; // 0x1 + } + + let _ = b.next(); + { + let mut nlh = b.current_nlmsg(); + nlh.put_header(); + *nlh.nlmsg_type = linux::netlink::NLMSG_ERROR; // 0x2 + } + + let _ = b.next(); + { + let mut nlh = b.current_nlmsg(); + nlh.put_header(); + *nlh.nlmsg_type = linux::netlink::NLMSG_DONE; // 0x3 + } + + let _ = b.next(); + { + let mut nlh = b.current_nlmsg(); + nlh.put_header(); + *nlh.nlmsg_type = linux::netlink::NLMSG_OVERRUN;// 0x4 + } + + let mut ctlcbs + = [None, + Some(nlmsg_cb_ok()), // NLMSG_NOOP + Some(nlmsg_cb_ok()), // NLMSG_ERROR + Some(nlmsg_cb_ok()), // NLMSG_DONE + Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN + // bufsize = 16 * 4 + assert!(mnl::cb_run4(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::OK); + + ctlcbs + = [None, + Some(nlmsg_cb_ok()), // NLMSG_NOOP + Some(nlmsg_cb_error()), // NLMSG_ERROR + Some(nlmsg_cb_ok()), // NLMSG_DONE + Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN + assert!(mnl::cb_run4(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).is_err()); + + ctlcbs + = [None, + Some(nlmsg_cb_ok()), // NLMSG_NOOP + Some(nlmsg_cb_ok()), // NLMSG_ERROR + Some(nlmsg_cb_stop()), // NLMSG_DONE + Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN + assert!(mnl::cb_run4(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::STOP); +} From 946e0b8f4b668d6b53f9f5eea4eddc643ea51b47 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Wed, 24 May 2017 17:44:52 +0900 Subject: [PATCH 08/27] mnl: change functions name that uses closure --- examples/genl/genl-family-get2.rs | 8 ++++---- examples/rtnl/rtnl-route-dump2.rs | 8 ++++---- src/lib.rs | 12 ++++++------ tests/lib.rs | 10 +++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/genl/genl-family-get2.rs b/examples/genl/genl-family-get2.rs index 3e2a6d7..38515bf 100644 --- a/examples/genl/genl-family-get2.rs +++ b/examples/genl/genl-family-get2.rs @@ -50,7 +50,7 @@ fn parse_genl_mc_grps(nested: &mnl::Attr) { let mut tb: [Option<&mnl::Attr>; genl::CTRL_ATTR_MCAST_GRP_MAX as usize + 1] = [None; genl::CTRL_ATTR_MCAST_GRP_MAX as usize + 1]; - let _ = pos.parse_nested2(parse_mc_grps_cb(&mut tb)); + let _ = pos.cl_parse_nested(parse_mc_grps_cb(&mut tb)); tb[genl::CtrlAttrMcastGrp::ID as usize] .map(|attr| print!("id-0x{:x} ", attr.u32())); @@ -65,7 +65,7 @@ fn parse_genl_family_ops<'a>(nested: &mnl::Attr) { let mut tb: [Option<&'a mnl::Attr>; genl::CTRL_ATTR_OP_MAX as usize + 1] = [None; genl::CTRL_ATTR_OP_MAX as usize + 1]; - let _ = pos.parse_nested2(Box::new(|attr: &'a mnl::Attr| { + let _ = pos.cl_parse_nested(Box::new(|attr: &'a mnl::Attr| { if let Err(_) = attr.type_valid(genl::CTRL_ATTR_OP_MAX) { return mnl::CbRet::OK; } @@ -147,7 +147,7 @@ fn data_cb() -> Box mnl::CbRet> { let mut tb: [Option<&mnl::Attr>; genl::CTRL_ATTR_MAX as usize + 1] = [None; genl::CTRL_ATTR_MAX as usize + 1]; - let _ = nlh.parse2(size_of::(), data_attr_cb(&mut tb)); + let _ = nlh.cl_parse(size_of::(), data_attr_cb(&mut tb)); tb[genl::CtrlAttr::FAMILY_NAME as usize] .map(|attr| print!("name={}\t", attr.str())); @@ -216,7 +216,7 @@ fn main() { let nrecv = nl.recvfrom(&mut buf) .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); - if mnl::cb_run3(&buf[0..nrecv], seq, portid, Some(data_cb())) + if mnl::cl_run(&buf[0..nrecv], seq, portid, Some(data_cb())) .unwrap_or_else(|errno| panic!("mnl_cb_run: {}", errno)) == mnl::CbRet::STOP { break; diff --git a/examples/rtnl/rtnl-route-dump2.rs b/examples/rtnl/rtnl-route-dump2.rs index e35159d..85921d2 100644 --- a/examples/rtnl/rtnl-route-dump2.rs +++ b/examples/rtnl/rtnl-route-dump2.rs @@ -66,7 +66,7 @@ fn attributes_show_ip(tb: &[Option<&mnl::Attr>]) { .map(|attr| { let mut tbx: [Option<&mnl::Attr>; rtnetlink::RTAX_MAX as usize + 1] = [None; rtnetlink::RTAX_MAX as usize + 1]; - let _ = attr.parse_nested2(Box::new(move |attr| { + let _ = attr.cl_parse_nested(Box::new(move |attr| { if let Err(_) = attr.type_valid(rtnetlink::RTAX_MAX as u16) { return mnl::CbRet::OK; } @@ -242,11 +242,11 @@ fn data_cb() -> Box mnl::CbRet> { = [None; rtnetlink::RTA_MAX as usize + 1]; match rm.rtm_family as c_int { libc::AF_INET => { - let _ = nlh.parse2(size_of::(), data_ipv4_attr_cb(&mut tb)); + let _ = nlh.cl_parse(size_of::(), data_ipv4_attr_cb(&mut tb)); attributes_show_ip::(&tb); }, libc::AF_INET6 => { - let _ = nlh.parse2(size_of::(), data_ipv6_attr_cb(&mut tb)); + let _ = nlh.cl_parse(size_of::(), data_ipv6_attr_cb(&mut tb)); attributes_show_ip::(&tb); }, _ => unreachable!() @@ -291,7 +291,7 @@ fn main() { .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); // if mnl::cb_run(&buf[0..nrecv], seq, portid, Some(data_cb), &mut None) - if mnl::cb_run3(&buf[0..nrecv], seq, portid, Some(data_cb())) + if mnl::cl_run(&buf[0..nrecv], seq, portid, Some(data_cb())) .unwrap_or_else(|errno| panic!("mnl_cb_run: {}", errno)) == mnl::CbRet::STOP { break; diff --git a/src/lib.rs b/src/lib.rs index 8e707e0..3432fd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -987,7 +987,7 @@ impl <'a> Nlmsg <'a> { cvt_cbret!(mnl_attr_parse(self.as_raw_ref(), offset as c_uint, attr_parse_cb::, pdata)) } - pub fn parse2<'b, 'c>(&self, offset: usize, cb: Box CbRet + 'c>) -> io::Result<(CbRet)> { + pub fn cl_parse<'b, 'c>(&self, offset: usize, cb: Box CbRet + 'c>) -> io::Result<(CbRet)> { cvt_cbret!(mnl_attr_parse(self.as_raw_ref(), offset as c_uint, attr_parse_cb2, Box::into_raw(Box::new(cb)) as *mut c_void)) } @@ -1318,7 +1318,7 @@ impl <'a> Attr { cvt_cbret!(mnl_attr_parse_nested(self, attr_parse_cb::, pdata)) } - pub fn parse_nested2<'b>(&self, cb: Box CbRet + 'b>) -> io::Result<(CbRet)> { + pub fn cl_parse_nested<'b>(&self, cb: Box CbRet + 'b>) -> io::Result<(CbRet)> { cvt_cbret!(mnl_attr_parse_nested(self, attr_parse_cb2, Box::into_raw(Box::new(cb)) as *mut c_void)) } @@ -1429,9 +1429,9 @@ pub fn cb_run<'a, T>(buf: &[u8], seq: u32, portid: u32, seq, portid, nlmsg_parse_cb::, argp)) } -pub fn cb_run3(buf: &[u8], seq: u32, portid: u32, - cb_data: Option CbRet>>) - -> io::Result<(CbRet)> { +pub fn cl_run(buf: &[u8], seq: u32, portid: u32, + cb_data: Option CbRet>>) + -> io::Result<(CbRet)> { cvt_cbret!(mnl_cb_run(buf.as_ptr() as *const c_void, buf.len() as size_t, seq, portid, nlmsg_parse_cb2, Box::into_raw(Box::new((cb_data, &[None:: CbRet>>]))) as *mut c_void)) @@ -1471,7 +1471,7 @@ pub fn cb_run2<'a, T: 'a>(buf: &[u8], seq: u32, portid: u32, raw_ctl_cbs.as_ptr() as *const CbT, ctlen as c_uint)) } -pub fn cb_run4(buf: &[u8], seq: u32, portid: u32, +pub fn cl_run2(buf: &[u8], seq: u32, portid: u32, cb_data: Option CbRet>>, cb_ctl_array: &mut [Option CbRet>>]) -> io::Result<(CbRet)> { diff --git a/tests/lib.rs b/tests/lib.rs index 3c924f5..d93e44c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -862,7 +862,7 @@ fn nlmsg_parse_2() { nlh.put_u8(3, 0x13); nlh.put_u8(4, 0x14); let mut data = 1; - assert!(nlh.parse2(0, Box::new(|attr| { + assert!(nlh.cl_parse(0, Box::new(|attr| { if attr.nla_type as u8 != data { return mnl::CbRet::ERROR; } @@ -877,7 +877,7 @@ fn nlmsg_parse_2() { let mut nlh = mnl::Nlmsg::new(&mut buf); nlh.put_u8(0, 0x0); let mut data = 1; - assert!(nlh.parse2(0, Box::new(|attr| { + assert!(nlh.cl_parse(0, Box::new(|attr| { if attr.nla_type as u8 != data { return mnl::CbRet::ERROR; } @@ -1087,7 +1087,7 @@ fn nlmsg_cb_run4() { Some(nlmsg_cb_ok()), // NLMSG_DONE Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN // bufsize = 16 * 4 - assert!(mnl::cb_run4(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::OK); + assert!(mnl::cl_run2(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::OK); ctlcbs = [None, @@ -1095,7 +1095,7 @@ fn nlmsg_cb_run4() { Some(nlmsg_cb_error()), // NLMSG_ERROR Some(nlmsg_cb_ok()), // NLMSG_DONE Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN - assert!(mnl::cb_run4(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).is_err()); + assert!(mnl::cl_run2(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).is_err()); ctlcbs = [None, @@ -1103,5 +1103,5 @@ fn nlmsg_cb_run4() { Some(nlmsg_cb_ok()), // NLMSG_ERROR Some(nlmsg_cb_stop()), // NLMSG_DONE Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN - assert!(mnl::cb_run4(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::STOP); + assert!(mnl::cl_run2(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::STOP); } From 51f83a2755b90417c84c3e9a0a6abb5f85b2a9ea Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Wed, 24 May 2017 18:06:55 +0900 Subject: [PATCH 09/27] mnl: rename nlmsg_batch next to proceed_next --- examples/netfilter/nfct-create-batch.rs | 2 +- examples/netfilter/nfct-create-batch2.rs | 2 +- src/lib.rs | 2 +- tests/lib.rs | 32 ++++++++++++------------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/netfilter/nfct-create-batch.rs b/examples/netfilter/nfct-create-batch.rs index be383f8..b4d7b5a 100644 --- a/examples/netfilter/nfct-create-batch.rs +++ b/examples/netfilter/nfct-create-batch.rs @@ -144,7 +144,7 @@ fn main() { put_msg(&mut b.current_nlmsg(), i, seq + i as u32 - 1024); // is there room for more messages in this batch? // if so, continue. - if b.next() { + if b.proceed_next() { continue; } send_batch(nl, b, portid); diff --git a/examples/netfilter/nfct-create-batch2.rs b/examples/netfilter/nfct-create-batch2.rs index 8a36025..41e43e8 100644 --- a/examples/netfilter/nfct-create-batch2.rs +++ b/examples/netfilter/nfct-create-batch2.rs @@ -135,7 +135,7 @@ fn main() { put_msg(&mut b.current_nlmsg(), i, seq + i as u32 - 1024); // is there room for more messages in this batch? // if so, continue. - if b.next() { + if b.proceed_next() { continue; } send_batch(nl, b, portid); diff --git a/src/lib.rs b/src/lib.rs index 3432fd6..1971f76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1063,7 +1063,7 @@ impl NlmsgBatch { /// /// You have to put at least one message in the batch before calling this /// function, otherwise your application is likely to crash. - pub fn next(&self) -> bool { + pub fn proceed_next(&self) -> bool { unsafe { mnl_nlmsg_batch_next(self) } } diff --git a/tests/lib.rs b/tests/lib.rs index d93e44c..cde87a3 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -916,47 +916,47 @@ fn nlmsg_batch_start() { fn nlmsg_batch_next() { let mut buf = vec![0u8; 512]; let b = mnl::NlmsgBatch::start(&mut buf, 512 / 2).unwrap(); - assert!(b.next() == true); + assert!(b.proceed_next() == true); { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 1; } - assert!(b.next() == false); + assert!(b.proceed_next() == false); } #[test] fn nlmsg_batch_size() { let mut buf = vec![0u8; 512]; let b = mnl::NlmsgBatch::start(&mut buf, 512 / 2).unwrap(); - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.size() == 0); { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 128; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.size() == 128); { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 128; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.size() == 256); { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 1; } - assert!(b.next() == false); + assert!(b.proceed_next() == false); assert!(b.size() == 256); } @@ -968,7 +968,7 @@ fn nlmsg_batch_reset() { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.size() == 256); b.reset(); assert!(b.size() == 0); @@ -977,12 +977,12 @@ fn nlmsg_batch_reset() { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == false); + assert!(b.proceed_next() == false); b.reset(); assert!(b.size() == 256); } @@ -998,7 +998,7 @@ fn nlmsg_batch_head() { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.head::() as *const u8 == bufptr); } @@ -1013,7 +1013,7 @@ fn nlmsg_batch_current() { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.current::() as *const u8 == unsafe { bufptr.offset(256) }); } @@ -1028,7 +1028,7 @@ fn nlmsg_batch_is_empty() { let mut nlh = b.current_nlmsg(); *nlh.nlmsg_len = 256; } - assert!(b.next() == true); + assert!(b.proceed_next() == true); assert!(b.is_empty() == false); b.reset(); assert!(b.is_empty() == true); @@ -1059,21 +1059,21 @@ fn nlmsg_cb_run4() { *nlh.nlmsg_type = linux::netlink::NLMSG_NOOP; // 0x1 } - let _ = b.next(); + let _ = b.proceed_next(); { let mut nlh = b.current_nlmsg(); nlh.put_header(); *nlh.nlmsg_type = linux::netlink::NLMSG_ERROR; // 0x2 } - let _ = b.next(); + let _ = b.proceed_next(); { let mut nlh = b.current_nlmsg(); nlh.put_header(); *nlh.nlmsg_type = linux::netlink::NLMSG_DONE; // 0x3 } - let _ = b.next(); + let _ = b.proceed_next(); { let mut nlh = b.current_nlmsg(); nlh.put_header(); From 762809f5bce9c8c8a5f8e4e5c22d5b572f616249 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 26 May 2017 15:41:29 +0900 Subject: [PATCH 10/27] mnl: nlmsg iterator fix and re-implement iterator for Nlmsg and add for NlmsgBatch --- src/lib.rs | 84 ++++++++++++++++++++++++++++------ src/nlmsg_ext.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++- tests/lib.rs | 44 ++++++++++++++++-- 3 files changed, 226 insertions(+), 19 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1971f76..41a9cc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,7 +116,7 @@ extern { fn mnl_nlmsg_batch_stop(b: *mut NlmsgBatch); // fn mnl_nlmsg_batch_size(b: *mut NlmsgBatch) -> size_t; fn mnl_nlmsg_batch_size(b: *const NlmsgBatch) -> size_t; - fn mnl_nlmsg_batch_reset(b: *mut NlmsgBatch); + // fn mnl_nlmsg_batch_reset(b: *mut NlmsgBatch); fn mnl_nlmsg_batch_head(b: *mut NlmsgBatch) -> *mut c_void; fn mnl_nlmsg_batch_current(b: *mut NlmsgBatch) -> *mut c_void; // fn mnl_nlmsg_batch_is_empty(b: *mut NlmsgBatch) -> bool; @@ -124,7 +124,14 @@ extern { } extern { // arbitrary function + fn mnl_nlmsg_put_header_check(buf: *mut c_void, buflen: size_t) -> *mut netlink::Nlmsghdr; + fn mnl_nlmsg_put_extra_header_check(nlh: *mut netlink::Nlmsghdr, buflen: size_t, size: size_t) -> *mut c_void; fn mnl_nlmsg_batch_rest(b: *const NlmsgBatch) -> size_t; + fn rsmnl_nlmsg_batch_start(buf: *mut c_void, bufsiz: size_t) -> *mut NlmsgBatch; + fn rsmnl_nlmsg_batch_reset(b: *mut NlmsgBatch); + fn rsmnl_nlmsg_batch_next(b: *mut NlmsgBatch) -> *mut netlink::Nlmsghdr; + fn rsmnl_nlmsg_batch_cap(b: *mut NlmsgBatch); + fn rsmnl_nlmsg_batch_put_back(b: *mut NlmsgBatch); } @@ -445,7 +452,6 @@ impl AsRawFd for Socket { pub struct Nlmsg <'a> { buf: &'a mut [u8], - remaining: isize, pub nlmsg_len: &'a mut u32, pub nlmsg_type: &'a mut u16, pub nlmsg_flags: &'a mut u16, @@ -458,7 +464,7 @@ impl <'a> Nlmsg <'a> { self.buf.len() } - fn as_raw_ref(&self) -> &netlink::Nlmsghdr { + pub fn as_raw_ref(&self) -> &netlink::Nlmsghdr { unsafe { (self.buf.as_ptr() as *const netlink::Nlmsghdr).as_ref().unwrap() } } @@ -490,11 +496,9 @@ impl <'a> Nlmsg <'a> { pub fn from_bytes(buf: &'a mut [u8]) -> Self { // XXX: check buf len > sizeof(Nlmsg) - let buflen = buf.len() as isize; let p = buf.as_mut_ptr(); let nlh = Nlmsg { buf: buf, - remaining: buflen, nlmsg_len: unsafe { (p as *mut u32).offset(0).as_mut().unwrap() }, nlmsg_type: unsafe { (p as *mut u16).offset(2).as_mut().unwrap() }, nlmsg_flags: unsafe { (p as *mut u16).offset(3).as_mut().unwrap() }, @@ -566,7 +570,7 @@ impl <'a> Nlmsg <'a> { unsafe { mnl_nlmsg_ok(self.as_raw_ref(), len as c_int) } } - pub fn raw_next<'b: 'a>(&'b mut self, len: isize) -> (Self, isize) { + pub fn next<'b: 'a>(&'b mut self, len: isize) -> (Self, isize) { let mut rest = len as c_int; let _ = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut rest)) }; let u = self.buf.len() - rest as usize; @@ -998,15 +1002,42 @@ impl <'a> Nlmsg <'a> { } } -impl <'a> Iterator for Nlmsg<'a> { - type Item = Self; +pub struct NlmsgIterator<'a> { + nlh: &'a mut netlink::Nlmsghdr, + remaining: usize, +} - fn next(&mut self) -> Option { - if ! unsafe { mnl_nlmsg_ok(self.as_raw_ref(), self.remaining as c_int) } { - return None; +impl <'a> Iterator for NlmsgIterator<'a> { + type Item = Nlmsg<'a>; + + fn next(&mut self) -> Option> { + let ret = self.nlh as *const netlink::Nlmsghdr; + unsafe { + if ! mnl_nlmsg_ok(self.nlh, self.remaining as c_int) { + return None; + } + let nlh = &mut *(mnl_nlmsg_next(self.nlh, &mut (self.remaining as c_int))); + if nlh.nlmsg_len == 0 { + return None; + } + self.nlh = nlh; + } + Some(Nlmsg::from_raw(ret)) + } +} + +impl <'a> IntoIterator for Nlmsg<'a> { + type Item = Nlmsg<'a>; + type IntoIter = NlmsgIterator<'a>; + + fn into_iter(self) -> NlmsgIterator<'a> { + let buflen = self.buf.len(); + NlmsgIterator { + nlh: unsafe { + &mut *(self.buf.as_mut_ptr() as *mut netlink::Nlmsghdr) + }, + remaining: buflen } - let nlh = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut (self.remaining as c_int))) }; - Some(Self::from_raw(nlh)) } } @@ -1083,7 +1114,7 @@ impl NlmsgBatch { /// new one. This function moves the last message which does not fit the /// batch to the head of the buffer, if any. pub fn reset(&mut self) { - unsafe { mnl_nlmsg_batch_reset(self) } + unsafe { rsmnl_nlmsg_batch_reset(self) } } /// get head of this batch @@ -1117,9 +1148,34 @@ impl NlmsgBatch { unsafe { mnl_nlmsg_batch_is_empty(self) } } + /// Not in original libmnl + pub fn new<'a>(buf: &'a mut [u8]) -> io::Result<&'a mut NlmsgBatch> { + cvt_null!(rsmnl_nlmsg_batch_start(buf.as_ptr() as *mut c_void, buf.len() as size_t)) + } + pub fn rest(&self) -> usize { unsafe { mnl_nlmsg_batch_rest(self) as usize } } + + pub fn cap(&mut self) { + unsafe { rsmnl_nlmsg_batch_cap(self) }; + } + + pub fn put_back(&mut self) { + unsafe { rsmnl_nlmsg_batch_put_back(self) }; + } +} + +impl <'a> Iterator for &'a mut NlmsgBatch { + type Item = Nlmsg<'a>; + + fn next(&mut self) -> Option> { + let nlh = unsafe { rsmnl_nlmsg_batch_next(*self) }; + if nlh.is_null() { + return None; + } + Some(Nlmsg::from_raw_parts(nlh as *mut u8, self.rest())) + } } pub type Attr = netlink::Nlattr; diff --git a/src/nlmsg_ext.c b/src/nlmsg_ext.c index c7f24fe..dcde3a5 100644 --- a/src/nlmsg_ext.c +++ b/src/nlmsg_ext.c @@ -1,19 +1,55 @@ +#include #include #include +#include +#include #include +#define EXPORT_SYMBOL(x) + +/** + * mnl_nlmsg_put_header_check - reserve and prepare room for Netlink header + * \param buf memory already allocated to store the Netlink header + * \param buflen size of buffer which stores the message + * + * This function first checks that the Netlink header can be added to the memory + * buffer passed as parameterthen sets to zero the buffer that is required to + * put the Netlink header in it. This function also initializes the nlmsg_len + * field to the size of the Netlink header. This function returns a pointer to + * the Netlink header structure. + * This function returns NULL on error and errno is set to EINVAL. + */ +EXPORT_SYMBOL(mnl_nlmsg_put_header_check); struct nlmsghdr *mnl_nlmsg_put_header_check(void *buf, size_t buflen) { - if (MNL_NLMSG_HDRLEN < buflen) + if (MNL_NLMSG_HDRLEN < buflen) { + errno = EINVAL; return NULL; + } return mnl_nlmsg_put_header(buf); } +/** + * mnl_nlmsg_put_extra_header - reserve and prepare room for an extra header + * \param nlh pointer to Netlink header + * \param buflen size of buffer which stores the message + * \param size size of the extra header that we want to put + * + * This function first checks the room that is required to put the extra header + * after the initial Netlink header can be added (fits into the buffer) and then + * sets to zero the room. This function also increases the nlmsg_len field. You + * have to invoke mnl_nlmsg_put_header() before you call this function. This + * function returns a pointer to the extra header. + * This function returns NULL on error and errno is set to EINVAL. + */ +EXPORT_SYMBOL(mnl_nlmsg_put_extra_header_check); void *mnl_nlmsg_put_extra_header_check(struct nlmsghdr *nlh, size_t buflen, size_t size) { - if (nlh->nlmsg_len + MNL_ALIGN(size) > buflen) + if (nlh->nlmsg_len + MNL_ALIGN(size) > buflen) { + errno = EINVAL; return NULL; + } return mnl_nlmsg_put_extra_header(nlh, size); } @@ -28,7 +64,84 @@ struct mnl_nlmsg_batch { bool overflow; }; +/** + * mnl_nlmsg_batch_rest - get the rest of the batch buffer size + * \param b pointer to batch + * + * This function returns the rest of the batch buffer size + */ +EXPORT_SYMBOL(mnl_nlmsg_batch_rest); size_t mnl_nlmsg_batch_rest(const struct mnl_nlmsg_batch *b) { return b->limit - b->buflen; } + +/* + * Belows will not be merged to master. + * Assume never overflow buffer. + */ +struct nlmsghdr *rsmnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b) +{ + struct nlmsghdr *nlh = b->cur; + + if (b->buflen + nlh->nlmsg_len + MNL_NLMSG_HDRLEN > b->limit) + return NULL; + + b->cur = b->buf + b->buflen + nlh->nlmsg_len; + b->buflen += nlh->nlmsg_len; + + return (struct nlmsghdr *)b->cur; +} + +/* adding clearing buffer to the original */ +struct mnl_nlmsg_batch *rsmnl_nlmsg_batch_start(void *buf, size_t limit) +{ + struct mnl_nlmsg_batch *b; + + b = malloc(sizeof(struct mnl_nlmsg_batch)); + if (b == NULL) + return NULL; + + b->buf = buf; + b->limit = limit; + b->buflen = 0; + b->cur = buf; + b->overflow = false; + memset(b->buf, 0, b->limit); + + return b; +} + +/* adding clearing buffer to the original */ +struct nlmsghdr *rsmnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b) +{ + if (b->overflow) { + struct nlmsghdr *nlh = b->cur; + memcpy(b->buf, b->cur, nlh->nlmsg_len); + memset(b->buf + nlh->nlmsg_len, 0, b->limit - nlh->nlmsg_len); + b->buflen = nlh->nlmsg_len; + b->cur = b->buf + b->buflen; + b->overflow = false; + } else { + b->buflen = 0; + b->cur = b->buf; + memset(b->buf, 0, b->limit); + } +} + +bool rsmnl_nlmsg_batch_cap(struct mnl_nlmsg_batch *b) +{ + struct nlmsghdr *nlh = b->cur; + + if (b->buflen + nlh->nlmsg_len > b->limit) + return; + + b->cur = b->buf + b->buflen + nlh->nlmsg_len; + b->buflen += nlh->nlmsg_len; +} + +void rsmnl_nlmsg_batch_put_back(struct mnl_nlmsg_batch *b) +{ + struct nlmsghdr *nlh = b->cur; + nlh->nlmsg_len = 0; +} diff --git a/tests/lib.rs b/tests/lib.rs index cde87a3..bdae045 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -2,6 +2,7 @@ use std::os::unix::io::AsRawFd; use std::mem::size_of; use std::iter::repeat; // use std::io::Cursor; +use std::iter::Iterator; extern crate crslmnl as mnl; use mnl::linux as linux; @@ -150,9 +151,8 @@ fn nlmsg_next_header() { let mut buf: Vec = repeat(0u8).take(512).collect(); { let mut nlh = mnl::Nlmsg::new(&mut buf); - // let (next_nlh, rest) = nlh.next(512); - let next_nlh = nlh.next().unwrap(); - // assert!(rest == 512 - hdrlen as isize); + let (next_nlh, rest) = nlh.next(512); + assert!(rest == 512 - hdrlen as isize); assert!(*next_nlh.nlmsg_len == 0); *next_nlh.nlmsg_len = 0x11111111; } @@ -1105,3 +1105,41 @@ fn nlmsg_cb_run4() { Some(nlmsg_cb_ok()), ]; // NLMSG_OVERRUN assert!(mnl::cl_run2(b.head::<[u8; 48]>(), 0, 0, None, &mut ctlcbs[..]).unwrap() == mnl::CbRet::STOP); } + +#[test] +fn nlmsg_batch_iterator() { + let mut buf = [0u8; 64]; + { + let b = mnl::NlmsgBatch::new(&mut buf[..]).unwrap(); + for (i, mut nlh) in b.enumerate() { + nlh.put_header(); // *nlh.nlmsg_len = 16; + *nlh.nlmsg_type = i as u16; + } + b.cap(); + assert!(b.size() == 64); + } + { + for (i, nlh) in mnl::Nlmsg::from_bytes(&mut buf[..]).into_iter().enumerate() { + assert!(*nlh.nlmsg_type == i as u16); + for (j, my) in nlh.into_iter().enumerate() { + assert!(*my.nlmsg_type == (i + j) as u16); + } + } + } + + { + let b = mnl::NlmsgBatch::new(&mut buf[..]).unwrap(); + for (i, mut nlh) in b.enumerate() { + nlh.put_header(); // *nlh.nlmsg_len = 16; + *nlh.nlmsg_type = i as u16; + } + b.put_back(); + b.cap(); + assert!(b.size() == 48); + } + { + for (i, nlh) in mnl::Nlmsg::from_bytes(&mut buf[..]).into_iter().enumerate() { + assert!(*nlh.nlmsg_type == i as u16); + } + } +} From b31ec9017d5e9e43b7b9ad9b64984cdea1d71ee3 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 29 May 2017 09:53:19 +0900 Subject: [PATCH 11/27] mnl: update constructor to return io::Result not Nlmsg This causes different behavior from the original in nlmsg_batch handling. The original does not have buf size, but assumes its buf size is double of the limit. Then it can return next buf event it exceeds the limit. This wrapper does not assume a such, just holding its limit as same as the buf size, so that it can not next if it exceeds the limit --- src/lib.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 41a9cc1..49f6b6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -494,8 +494,10 @@ impl <'a> Nlmsg <'a> { unsafe { mnl_nlmsg_get_payload_len(self.as_raw_ref()) } } - pub fn from_bytes(buf: &'a mut [u8]) -> Self { - // XXX: check buf len > sizeof(Nlmsg) + pub fn from_bytes(buf: &'a mut [u8]) -> io::Result { + if buf.len() < NLMSG_HDRLEN() as usize { + return Err(io::Error::from_raw_os_error(libc::EINVAL)); + } let p = buf.as_mut_ptr(); let nlh = Nlmsg { buf: buf, @@ -505,7 +507,7 @@ impl <'a> Nlmsg <'a> { nlmsg_seq: unsafe { (p as *mut u32).offset(2).as_mut().unwrap() }, nlmsg_pid: unsafe { (p as *mut u32).offset(3).as_mut().unwrap() }, }; - nlh + Ok(nlh) } /// create, reserve and prepare room for Netlink header @@ -518,13 +520,13 @@ impl <'a> Nlmsg <'a> { /// header in the memory buffer passed as parameter. This function also /// initializes the nlmsg_len field to the size of the Netlink header. This /// function returns a Netlink header structure. - pub fn new(buf: &'a mut [u8]) -> Self { - let mut nlh = Self::from_bytes(buf); + pub fn new(buf: &'a mut [u8]) -> io::Result { + let mut nlh = try!(Self::from_bytes(buf)); nlh.put_header(); - nlh + Ok(nlh) } - fn from_raw(nlh: *const netlink::Nlmsghdr) -> Self { + fn from_raw(nlh: *const netlink::Nlmsghdr) -> io::Result { let buf: &'a mut[u8] = unsafe { std::slice::from_raw_parts_mut((nlh as *mut u8), (*nlh).nlmsg_len as usize) @@ -532,7 +534,7 @@ impl <'a> Nlmsg <'a> { Self::from_bytes(buf) } - fn from_raw_parts(p: *mut u8, size: usize) -> Self { + fn from_raw_parts(p: *mut u8, size: usize) -> io::Result { let buf: &'a mut[u8] = unsafe { std::slice::from_raw_parts_mut(p, size) }; @@ -570,7 +572,7 @@ impl <'a> Nlmsg <'a> { unsafe { mnl_nlmsg_ok(self.as_raw_ref(), len as c_int) } } - pub fn next<'b: 'a>(&'b mut self, len: isize) -> (Self, isize) { + pub fn next<'b: 'a>(&'b mut self, len: isize) -> (io::Result, isize) { let mut rest = len as c_int; let _ = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut rest)) }; let u = self.buf.len() - rest as usize; @@ -1022,7 +1024,7 @@ impl <'a> Iterator for NlmsgIterator<'a> { } self.nlh = nlh; } - Some(Nlmsg::from_raw(ret)) + Some(Nlmsg::from_raw(ret).unwrap()) } } @@ -1135,7 +1137,7 @@ impl NlmsgBatch { unsafe { &mut(*(mnl_nlmsg_batch_current(self) as *mut T)) } } - pub fn current_nlmsg(&mut self) -> Nlmsg { + pub fn current_nlmsg(&mut self) -> io::Result { let p = unsafe { mnl_nlmsg_batch_current(self) as *mut u8 }; Nlmsg::from_raw_parts(p, self.rest()) } @@ -1174,7 +1176,7 @@ impl <'a> Iterator for &'a mut NlmsgBatch { if nlh.is_null() { return None; } - Some(Nlmsg::from_raw_parts(nlh as *mut u8, self.rest())) + Some(Nlmsg::from_raw_parts(nlh as *mut u8, self.rest()).unwrap()) } } @@ -1433,7 +1435,7 @@ extern fn nlmsg_parse_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_ unsafe { let arg = &mut *(data as *mut CbData); if let Some(cb) = arg.cb { - return cb(Nlmsg::from_raw(nlh), arg.data) as c_int; + return cb(Nlmsg::from_raw(nlh).unwrap(), arg.data) as c_int; } CbRet::OK as c_int // MNL_CB_OK } @@ -1445,7 +1447,7 @@ extern fn nlmsg_parse_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c &[Option CbRet>>])); let mut rc = CbRet::OK as c_int; if let Some(ref mut cb) = op.0.as_mut() { - rc = cb(Nlmsg::from_raw(nlh)) as c_int; + rc = cb(Nlmsg::from_raw(nlh).unwrap()) as c_int; } forget(op); rc @@ -1456,7 +1458,7 @@ extern fn nlmsg_ctl_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_vo unsafe { let arg = &mut *(data as *mut CbData); if let Some(ctl_cb) = arg.ctl_cbs[(*nlh).nlmsg_type as usize] { - return ctl_cb(Nlmsg::from_raw(nlh), arg.data) as c_int; + return ctl_cb(Nlmsg::from_raw(nlh).unwrap(), arg.data) as c_int; } CbRet::OK as c_int // MNL_CB_OK } @@ -1467,7 +1469,7 @@ extern fn nlmsg_ctl_cb2(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_i let mut cbs = Box::from_raw(data as *mut (Option CbRet>>, &mut [Option CbRet>>])); let rc = match cbs.1[(*nlh).nlmsg_type as usize] { - Some(ref mut cb) => cb(Nlmsg::from_raw(nlh)) as c_int, + Some(ref mut cb) => cb(Nlmsg::from_raw(nlh).unwrap()) as c_int, None => CbRet::OK as c_int, }; forget(cbs); From 9d28a28930e62e2b984cfad52232e2cd35347756 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 29 May 2017 11:18:28 +0900 Subject: [PATCH 12/27] examples, tests: follow the previous update --- examples/genl/genl-family-get.rs | 2 +- examples/genl/genl-family-get2.rs | 2 +- examples/netfilter/nf-log-pnet.rs | 6 +- examples/netfilter/nf-log.rs | 6 +- examples/netfilter/nf-log2.rs | 6 +- examples/netfilter/nf-queue-pnet.rs | 8 +- examples/netfilter/nf-queue.rs | 8 +- examples/netfilter/nfct-create-batch.rs | 2 +- examples/netfilter/nfct-create-batch2.rs | 2 +- examples/netfilter/nfct-daemon.rs | 2 +- examples/netfilter/nfct-dump.rs | 2 +- examples/rtnl/rtnl-addr-dump.rs | 2 +- examples/rtnl/rtnl-link-dump.rs | 2 +- examples/rtnl/rtnl-link-dump2.rs | 2 +- examples/rtnl/rtnl-link-dump3.rs | 2 +- examples/rtnl/rtnl-link-set.rs | 2 +- examples/rtnl/rtnl-route-add.rs | 2 +- examples/rtnl/rtnl-route-dump.rs | 2 +- examples/rtnl/rtnl-route-dump2.rs | 2 +- tests/lib.rs | 183 ++++++++++++----------- 20 files changed, 125 insertions(+), 120 deletions(-) diff --git a/examples/genl/genl-family-get.rs b/examples/genl/genl-family-get.rs index 159b3ad..ea8499c 100644 --- a/examples/genl/genl-family-get.rs +++ b/examples/genl/genl-family-get.rs @@ -185,7 +185,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = genl::GENL_ID_CTRL; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; diff --git a/examples/genl/genl-family-get2.rs b/examples/genl/genl-family-get2.rs index 38515bf..d3d18a6 100644 --- a/examples/genl/genl-family-get2.rs +++ b/examples/genl/genl-family-get2.rs @@ -192,7 +192,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = genl::GENL_ID_CTRL; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; diff --git a/examples/netfilter/nf-log-pnet.rs b/examples/netfilter/nf-log-pnet.rs index a679770..e0921ab 100644 --- a/examples/netfilter/nf-log-pnet.rs +++ b/examples/netfilter/nf-log-pnet.rs @@ -123,7 +123,7 @@ fn log_cb(nlh: mnl::Nlmsg, _: &mut Option) -> mnl::CbRet { } fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -137,7 +137,7 @@ fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg } fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -152,7 +152,7 @@ fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl } fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; diff --git a/examples/netfilter/nf-log.rs b/examples/netfilter/nf-log.rs index ac27113..93e782c 100644 --- a/examples/netfilter/nf-log.rs +++ b/examples/netfilter/nf-log.rs @@ -87,7 +87,7 @@ fn log_cb(nlh: mnl::Nlmsg, _: &mut Option) -> mnl::CbRet { } fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -101,7 +101,7 @@ fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg } fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -116,7 +116,7 @@ fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl } fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; diff --git a/examples/netfilter/nf-log2.rs b/examples/netfilter/nf-log2.rs index ee80afa..242afc3 100644 --- a/examples/netfilter/nf-log2.rs +++ b/examples/netfilter/nf-log2.rs @@ -88,7 +88,7 @@ fn log_cb(nlh: mnl::Nlmsg, _: &mut Option) -> mnl::CbRet { } fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -102,7 +102,7 @@ fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg } fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -117,7 +117,7 @@ fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl } fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; diff --git a/examples/netfilter/nf-queue-pnet.rs b/examples/netfilter/nf-queue-pnet.rs index 9e273fe..548c102 100644 --- a/examples/netfilter/nf-queue-pnet.rs +++ b/examples/netfilter/nf-queue-pnet.rs @@ -104,7 +104,7 @@ fn queue_cb(nlh: mnl::Nlmsg, packet_id: &mut u32) -> mnl::CbRet { } fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -123,7 +123,7 @@ fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { } fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -143,7 +143,7 @@ fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> m } fn nfq_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, queue_num: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -159,7 +159,7 @@ fn nfq_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, queue_num: } fn nfq_build_verdict<'a>(buf: &'a mut [u8], id: u32, queue_num: u16, verd: u32) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::VERDICT as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; let nfg = nlh.put_sized_header::(); diff --git a/examples/netfilter/nf-queue.rs b/examples/netfilter/nf-queue.rs index 69b74be..e611dc2 100644 --- a/examples/netfilter/nf-queue.rs +++ b/examples/netfilter/nf-queue.rs @@ -76,7 +76,7 @@ fn queue_cb(nlh: mnl::Nlmsg, packet_id: &mut u32) -> mnl::CbRet { } fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -95,7 +95,7 @@ fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { } fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -115,7 +115,7 @@ fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> m } fn nfq_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, queue_num: u16) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; @@ -131,7 +131,7 @@ fn nfq_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, queue_num: } fn nfq_build_verdict<'a>(buf: &'a mut [u8], id: u32, queue_num: u16, verd: u32) -> mnl::Nlmsg { - let mut nlh = mnl::Nlmsg::new(buf); + let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::VERDICT as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; let nfg = nlh.put_sized_header::(); diff --git a/examples/netfilter/nfct-create-batch.rs b/examples/netfilter/nfct-create-batch.rs index b4d7b5a..6b13414 100644 --- a/examples/netfilter/nfct-create-batch.rs +++ b/examples/netfilter/nfct-create-batch.rs @@ -141,7 +141,7 @@ fn main() { let seq = time::now().to_timespec().sec as u32; for i in 1024u16..65535 { - put_msg(&mut b.current_nlmsg(), i, seq + i as u32 - 1024); + put_msg(&mut b.current_nlmsg().unwrap(), i, seq + i as u32 - 1024); // is there room for more messages in this batch? // if so, continue. if b.proceed_next() { diff --git a/examples/netfilter/nfct-create-batch2.rs b/examples/netfilter/nfct-create-batch2.rs index 41e43e8..49b3f2c 100644 --- a/examples/netfilter/nfct-create-batch2.rs +++ b/examples/netfilter/nfct-create-batch2.rs @@ -132,7 +132,7 @@ fn main() { let seq = time::now().to_timespec().sec as u32; for i in 1024u16..65535 { - put_msg(&mut b.current_nlmsg(), i, seq + i as u32 - 1024); + put_msg(&mut b.current_nlmsg().unwrap(), i, seq + i as u32 - 1024); // is there room for more messages in this batch? // if so, continue. if b.proceed_next() { diff --git a/examples/netfilter/nfct-daemon.rs b/examples/netfilter/nfct-daemon.rs index f1efe1d..2c2e3ba 100644 --- a/examples/netfilter/nfct-daemon.rs +++ b/examples/netfilter/nfct-daemon.rs @@ -246,7 +246,7 @@ fn main() { let _ = nl.setsockopt::(netlink::NETLINK_NO_ENOBUFS, 1); let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); // Counters are atomically zeroed in each dump *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::IPCTNL_MSG_CT_GET_CTRZERO; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; diff --git a/examples/netfilter/nfct-dump.rs b/examples/netfilter/nfct-dump.rs index 0632c18..ef4bdb4 100644 --- a/examples/netfilter/nfct-dump.rs +++ b/examples/netfilter/nfct-dump.rs @@ -252,7 +252,7 @@ fn main() { let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::CtnlMsgTypes::GET as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-addr-dump.rs b/examples/rtnl/rtnl-addr-dump.rs index a448e41..adfd06a 100644 --- a/examples/rtnl/rtnl-addr-dump.rs +++ b/examples/rtnl/rtnl-addr-dump.rs @@ -88,7 +88,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_GETADDR; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-link-dump.rs b/examples/rtnl/rtnl-link-dump.rs index 95714f8..32d9423 100644 --- a/examples/rtnl/rtnl-link-dump.rs +++ b/examples/rtnl/rtnl-link-dump.rs @@ -97,7 +97,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_GETLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-link-dump2.rs b/examples/rtnl/rtnl-link-dump2.rs index 8fea39f..28c4a4b 100644 --- a/examples/rtnl/rtnl-link-dump2.rs +++ b/examples/rtnl/rtnl-link-dump2.rs @@ -68,7 +68,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_GETLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-link-dump3.rs b/examples/rtnl/rtnl-link-dump3.rs index 0b0bea6..8be93e4 100644 --- a/examples/rtnl/rtnl-link-dump3.rs +++ b/examples/rtnl/rtnl-link-dump3.rs @@ -65,7 +65,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_GETLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-link-set.rs b/examples/rtnl/rtnl-link-set.rs index e85c49c..e748e39 100644 --- a/examples/rtnl/rtnl-link-set.rs +++ b/examples/rtnl/rtnl-link-set.rs @@ -47,7 +47,7 @@ fn main() { let seq = time::now().to_timespec().sec as u32; let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_NEWLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-route-add.rs b/examples/rtnl/rtnl-route-add.rs index 73c706e..fa3dfe6 100644 --- a/examples/rtnl/rtnl-route-add.rs +++ b/examples/rtnl/rtnl-route-add.rs @@ -98,7 +98,7 @@ Example: {} eth0 10.0.1.12 32 10.0.1.11 let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_NEWROUTE; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_CREATE | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-route-dump.rs b/examples/rtnl/rtnl-route-dump.rs index 08d8bbb..f338f53 100644 --- a/examples/rtnl/rtnl-route-dump.rs +++ b/examples/rtnl/rtnl-route-dump.rs @@ -268,7 +268,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_GETROUTE; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/examples/rtnl/rtnl-route-dump2.rs b/examples/rtnl/rtnl-route-dump2.rs index 85921d2..0b2073d 100644 --- a/examples/rtnl/rtnl-route-dump2.rs +++ b/examples/rtnl/rtnl-route-dump2.rs @@ -272,7 +272,7 @@ fn main() { let mut buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; let seq = time::now().to_timespec().sec as u32; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); *nlh.nlmsg_type = rtnetlink::RTM_GETROUTE; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; diff --git a/tests/lib.rs b/tests/lib.rs index bdae045..f522cc9 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -118,14 +118,14 @@ fn nlmsg_size() { #[test] fn nlmsg_put_header() { let mut buf = vec![123 as u8; mnl::SOCKET_BUFFER_SIZE()]; - let nlh = mnl::Nlmsg::new(&mut buf); + let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(*nlh.nlmsg_len == 16); } #[test] fn nlmsg_put_extra_header() { let mut buf = vec![123 as u8; mnl::SOCKET_BUFFER_SIZE()]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); { let exthdr: &mut linux::netfilter::nfnetlink::Nfgenmsg = nlh.put_extra_header(size_of::()); @@ -139,7 +139,7 @@ fn nlmsg_put_extra_header() { #[test] fn nlmsg_ok() { let mut buf = vec![0; mnl::NLMSG_HDRLEN() as usize]; - let nlh = mnl::Nlmsg::new(&mut buf); + let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(!nlh.ok(15)); assert!(nlh.ok(16)); assert!(nlh.ok(17)); @@ -150,11 +150,12 @@ fn nlmsg_next_header() { let hdrlen = mnl::NLMSG_HDRLEN() as usize; let mut buf: Vec = repeat(0u8).take(512).collect(); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); let (next_nlh, rest) = nlh.next(512); + let nnlh = next_nlh.unwrap(); assert!(rest == 512 - hdrlen as isize); - assert!(*next_nlh.nlmsg_len == 0); - *next_nlh.nlmsg_len = 0x11111111; + assert!(*nnlh.nlmsg_len == 0); + *nnlh.nlmsg_len = 0x11111111; } assert_eq!(buf[hdrlen..(hdrlen + 4)], [0x11, 0x11, 0x11, 0x11]); } @@ -163,12 +164,12 @@ fn nlmsg_next_header() { fn nlmsg_seq_ok() { let mut buf =vec![0u8; 512]; { - let nlh = mnl::Nlmsg::new(&mut buf); + let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.seq_ok(0)); } set_nlmsg_seq(&mut buf, 1234567890); { - let nlh = mnl::Nlmsg::new(&mut buf); + let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.seq_ok(1234567890)); } } @@ -177,12 +178,12 @@ fn nlmsg_seq_ok() { fn nlmsg_porid_ok() { let mut buf =vec![0u8; 512]; { - let nlh = mnl::Nlmsg::new(&mut buf); + let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.portid_ok(0)); } set_nlmsg_seq(&mut buf, 1234567890); { - let nlh = mnl::Nlmsg::new(&mut buf); + let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.portid_ok(1234567890)); } } @@ -191,7 +192,7 @@ fn nlmsg_porid_ok() { fn nlmsg_payload() { let mut buf =vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); let v: &mut u64 = nlh.payload_mut(); *v = std::u64::MAX; assert!(*nlh.payload::() == std::u64::MAX); @@ -204,7 +205,7 @@ fn nlmsg_payload() { fn nlmsg_payload_offset() { let mut buf =vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); let v: &mut u64 = nlh.payload_offset_mut(128); *v = std::u64::MAX; assert!(*nlh.payload_offset::(128) == std::u64::MAX); @@ -219,7 +220,7 @@ fn nlmsg_payload_tail() { let mut buf =vec![0u8; 512]; set_nlmsg_len(&mut buf, 64); { - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let v: &mut u64 = nlh.payload_tail_mut(); *v = std::u64::MAX; assert!(*nlh.payload_tail::() == std::u64::MAX); @@ -233,7 +234,7 @@ fn nlmsg_put() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put(123, &std::u64::MAX); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -251,7 +252,7 @@ fn nlmsg_put_u8() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u8(12, 34); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -264,7 +265,7 @@ fn nlmsg_put_u8() { assert!(*buf_offset_as::(&buf, 20) == 34); { - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); nlh.put_u8(56, 78); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); @@ -282,7 +283,7 @@ fn nlmsg_put_u16() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u16(1234, 5678); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -295,7 +296,7 @@ fn nlmsg_put_u16() { assert!(*buf_offset_as::(&buf, 20) == 5678); { - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); nlh.put_u16(9012, 3456); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); @@ -313,7 +314,7 @@ fn nlmsg_put_u32() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u32(1234, 56789012); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -326,7 +327,7 @@ fn nlmsg_put_u32() { assert!(*buf_offset_as::(&buf, 20) == 56789012); { - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); nlh.put_u32(3456, 78901234); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); @@ -344,7 +345,7 @@ fn nlmsg_put_u64() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u64(1234, 0x567890abcdef0123); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -357,7 +358,7 @@ fn nlmsg_put_u64() { assert!(*buf_offset_as::(&buf, 20) == 0x567890abcdef0123); { - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); nlh.put_u64(4567, 0x890abcdef0123456); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); @@ -377,7 +378,7 @@ fn nlmsg_put_str() { let b1 = s1.as_bytes(); // .len() == 13 let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_str(1234, s1); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32)); @@ -394,7 +395,7 @@ fn nlmsg_put_str() { let attr_len2 = linux::netlink::NLA_HDRLEN() + (b2.len() as u16); let bi: isize; { - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; nlh.put_str(5678, s2); @@ -417,7 +418,7 @@ fn nlmsg_put_strz() { let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16) + 1; let mut nlmsg_len = mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_strz(1234, s1); assert!(*nlh.nlmsg_len == nlmsg_len); @@ -438,7 +439,7 @@ fn nlmsg_put_strz() { let bi: isize; { set_buf(&mut buf, attr_tail, 0xffu8); - let mut nlh = mnl::Nlmsg::from_bytes(&mut buf); + let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; nlh.put_strz(5678, s2); @@ -458,7 +459,7 @@ fn nlmsg_put_check() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_check(123, &std::u64::MAX)); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -473,13 +474,13 @@ fn nlmsg_put_check() { { let mut buf = vec![0u8; 39]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_check(123, &std::u64::MAX)); assert!(!nlh.put_check(234, &std::u64::MAX)); } { let mut buf = vec![0u8; 40]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_check(123, &std::u64::MAX)); assert!(nlh.put_check(234, &std::u64::MAX)); } @@ -490,7 +491,7 @@ fn nlmsg_put_u8_check() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u8_check(12, 34)); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -504,14 +505,14 @@ fn nlmsg_put_u8_check() { { let mut buf = vec![0u8; 31]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u8_check(12, 34)); assert!(!nlh.put_u8_check(56, 78)); } buf = vec![0u8; 32]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u8_check(12, 34)); let attr = nlh.payload_tail::(); assert!(nlh.put_u8_check(56, 78)); @@ -529,7 +530,7 @@ fn nlmsg_put_u16_check() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u16_check(1234, 5678)); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -543,14 +544,14 @@ fn nlmsg_put_u16_check() { { let mut buf = vec![0u8; 31]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u16_check(1234, 5678)); assert!(!nlh.put_u16_check(9012, 3456)); } let mut buf = vec![0u8; 32]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u16_check(1234, 5678)); let attr = nlh.payload_tail::(); assert!(nlh.put_u16_check(9012, 3456)); @@ -568,7 +569,7 @@ fn nlmsg_put_u32_check() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u32_check(1234, 56789012)); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -582,14 +583,14 @@ fn nlmsg_put_u32_check() { { let mut buf = vec![0u8; 31]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u32_check(1234, 56789012)); assert!(!nlh.put_u32_check(3456, 78901234)); } buf = vec![0u8; 32]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u32_check(1234, 56789012)); let attr = nlh.payload_tail::(); assert!(nlh.put_u32_check(3456, 78901234)); @@ -607,7 +608,7 @@ fn nlmsg_put_u64_check() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u64_check(1234, 0x567890abcdef0123)); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); @@ -621,14 +622,14 @@ fn nlmsg_put_u64_check() { { let mut buf = vec![0u8; 39]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u64_check(1234, 0x567890abcdef0123)); assert!(!nlh.put_u64_check(4567, 0x890abcdef0123456)); } buf = vec![0u8; 40]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_u64_check(1234, 0x567890abcdef0123)); let attr = nlh.payload_tail::(); assert!(nlh.put_u64_check(4567, 0x890abcdef0123456)); @@ -648,7 +649,7 @@ fn nlmsg_put_str_check() { let b1 = s1.as_bytes(); // .len() == 13 let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_str_check(1234, s1)); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32)); @@ -664,7 +665,7 @@ fn nlmsg_put_str_check() { { let mut buf = vec![0u8; 51]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_str_check(1234, s1)); assert!(!nlh.put_str_check(5678, s2)); } @@ -674,7 +675,7 @@ fn nlmsg_put_str_check() { let b2 = s2.as_bytes(); // .len() == 10 let attr_len2 = linux::netlink::NLA_HDRLEN() + (b2.len() as u16); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_str_check(1234, s1)); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; @@ -696,7 +697,7 @@ fn nlmsg_put_strz_check() { let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16) + 1; let mut nlmsg_len = mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32); { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_strz_check(1234, s1)); assert!(*nlh.nlmsg_len == nlmsg_len); @@ -712,7 +713,7 @@ fn nlmsg_put_strz_check() { let s2 = "My name is"; { let mut buf = vec![0u8; 51]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_strz_check(1234, s1)); assert!(!nlh.put_strz_check(5678, s2)); @@ -726,7 +727,7 @@ fn nlmsg_put_strz_check() { buf = vec![0u8; 52]; { set_buf(&mut buf, attr_tail, 0xffu8); - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.put_strz_check(1234, s1)); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; @@ -746,7 +747,7 @@ fn nlmsg_put_strz_check() { fn nlmsg_nest_start() { let mut buf = vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); let attr = nlh.nest_start(0x123); assert!(*nlh.nlmsg_len == linux::netlink::NLMSG_LENGTH(linux::netlink::NLA_HDRLEN() as u32)); @@ -762,12 +763,12 @@ fn nlmsg_nest_start_check() { let mut buf: std::vec::Vec; { buf = vec![0u8; 19]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); assert!(nlh.nest_start_check(0x123).is_none()); } { buf = vec![0u8; 20]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); if let Some(attr) = nlh.nest_start_check(0x123) { assert!(*nlh.nlmsg_len == linux::netlink::NLMSG_LENGTH(linux::netlink::NLA_HDRLEN() as u32)); assert!(attr.nla_len == 0); // will update after _end @@ -784,7 +785,7 @@ fn nlmsg_nest_start_check() { fn nlmsg_nest_end() { let mut buf = vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); let attr = nlh.nest_start(0x123); nlh.put_u8(0x4567, 0x89); nlh.put_u64(0xabcd, 0xef01234567890abc); @@ -807,7 +808,7 @@ fn nlmsg_nest_end() { fn nlmsg_nest_cancel() { let mut buf = vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); let mut attr = nlh.nest_start(0x123); nlh.nest_cancel(attr); @@ -838,7 +839,7 @@ fn nlmsg_parse_cb1(attr: &mnl::Attr, data: &mut u8) -> mnl::CbRet { fn nlmsg_parse() { let mut buf = vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u8(1, 0x11); nlh.put_u8(2, 0x12); nlh.put_u8(3, 0x13); @@ -846,7 +847,7 @@ fn nlmsg_parse() { assert!(nlh.parse(0, nlmsg_parse_cb1, &mut 1).unwrap() == mnl::CbRet::OK); } { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u8(0, 0x0); assert!(nlh.parse(0, nlmsg_parse_cb1, &mut 1).is_err()); } @@ -856,7 +857,7 @@ fn nlmsg_parse() { fn nlmsg_parse_2() { let mut buf = vec![0u8; 512]; { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u8(1, 0x11); nlh.put_u8(2, 0x12); nlh.put_u8(3, 0x13); @@ -874,7 +875,7 @@ fn nlmsg_parse_2() { })).unwrap() == mnl::CbRet::OK); } { - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u8(0, 0x0); let mut data = 1; assert!(nlh.cl_parse(0, Box::new(|attr| { @@ -894,7 +895,7 @@ fn nlmsg_parse_2() { #[test] fn nlmsg_attrs() { let mut buf = vec![0u8; 512]; - let mut nlh = mnl::Nlmsg::new(&mut buf); + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); nlh.put_u8(0, 0x10); nlh.put_u8(1, 0x11); nlh.put_u8(2, 0x12); @@ -919,16 +920,19 @@ fn nlmsg_batch_next() { assert!(b.proceed_next() == true); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 256; } assert!(b.proceed_next() == true); - { - let mut nlh = b.current_nlmsg(); - *nlh.nlmsg_len = 1; - } - assert!(b.proceed_next() == false); + // The original will success + // since assumes buf size limit is the half of the buf. + // But this limits equals to the size of buffer + // { + // let mut nlh = b.current_nlmsg().unwrap(); + // *nlh.nlmsg_len = 1; + // } + // assert!(b.proceed_next() == false); } #[test] @@ -939,25 +943,25 @@ fn nlmsg_batch_size() { assert!(b.size() == 0); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 128; } assert!(b.proceed_next() == true); assert!(b.size() == 128); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 128; } assert!(b.proceed_next() == true); assert!(b.size() == 256); - { - let mut nlh = b.current_nlmsg(); - *nlh.nlmsg_len = 1; - } - assert!(b.proceed_next() == false); - assert!(b.size() == 256); + // { + // let mut nlh = b.current_nlmsg().unwrap(); + // *nlh.nlmsg_len = 1; + // } + // assert!(b.proceed_next() == false); + // assert!(b.size() == 256); } #[test] @@ -965,7 +969,7 @@ fn nlmsg_batch_reset() { let mut buf = vec![0u8; 512]; let b = mnl::NlmsgBatch::start(&mut buf, 512 / 2).unwrap(); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 256; } assert!(b.proceed_next() == true); @@ -974,17 +978,18 @@ fn nlmsg_batch_reset() { assert!(b.size() == 0); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 256; } assert!(b.proceed_next() == true); - { - let mut nlh = b.current_nlmsg(); - *nlh.nlmsg_len = 256; - } - assert!(b.proceed_next() == false); - b.reset(); - assert!(b.size() == 256); + + // { + // let mut nlh = b.current_nlmsg().unwrap(); + // *nlh.nlmsg_len = 256; + // } + // assert!(b.proceed_next() == false); + // b.reset(); + // assert!(b.size() == 256); } #[test] @@ -995,7 +1000,7 @@ fn nlmsg_batch_head() { assert!(b.head::() as *const u8 == bufptr); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 256; } assert!(b.proceed_next() == true); @@ -1010,7 +1015,7 @@ fn nlmsg_batch_current() { assert!(b.current::() as *const u8 == bufptr); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 256; } assert!(b.proceed_next() == true); @@ -1025,7 +1030,7 @@ fn nlmsg_batch_is_empty() { assert!(b.is_empty() == true); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); *nlh.nlmsg_len = 256; } assert!(b.proceed_next() == true); @@ -1054,28 +1059,28 @@ fn nlmsg_cb_run4() { let mut buf = vec![0u8; 512]; let b = mnl::NlmsgBatch::start(&mut *buf, 512 / 2).unwrap(); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); nlh.put_header(); *nlh.nlmsg_type = linux::netlink::NLMSG_NOOP; // 0x1 } let _ = b.proceed_next(); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); nlh.put_header(); *nlh.nlmsg_type = linux::netlink::NLMSG_ERROR; // 0x2 } let _ = b.proceed_next(); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); nlh.put_header(); *nlh.nlmsg_type = linux::netlink::NLMSG_DONE; // 0x3 } let _ = b.proceed_next(); { - let mut nlh = b.current_nlmsg(); + let mut nlh = b.current_nlmsg().unwrap(); nlh.put_header(); *nlh.nlmsg_type = linux::netlink::NLMSG_OVERRUN;// 0x4 } @@ -1119,7 +1124,7 @@ fn nlmsg_batch_iterator() { assert!(b.size() == 64); } { - for (i, nlh) in mnl::Nlmsg::from_bytes(&mut buf[..]).into_iter().enumerate() { + for (i, nlh) in mnl::Nlmsg::from_bytes(&mut buf[..]).unwrap().into_iter().enumerate() { assert!(*nlh.nlmsg_type == i as u16); for (j, my) in nlh.into_iter().enumerate() { assert!(*my.nlmsg_type == (i + j) as u16); @@ -1138,7 +1143,7 @@ fn nlmsg_batch_iterator() { assert!(b.size() == 48); } { - for (i, nlh) in mnl::Nlmsg::from_bytes(&mut buf[..]).into_iter().enumerate() { + for (i, nlh) in mnl::Nlmsg::from_bytes(&mut buf[..]).unwrap().into_iter().enumerate() { assert!(*nlh.nlmsg_type == i as u16); } } From cfda83b19ce36b3db6efcef36011945fc60c6139 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 29 May 2017 12:33:16 +0900 Subject: [PATCH 13/27] mnl: add header size check functions --- src/lib.rs | 18 ++++++++++++++++++ src/nlmsg_ext.c | 4 ++-- tests/lib.rs | 24 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 49f6b6e..14d7052 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -550,6 +550,14 @@ impl <'a> Nlmsg <'a> { unsafe { &mut(*mnl_nlmsg_put_header(self.as_raw_mut() as *mut _ as *mut c_void)); } } + pub fn put_header_check(&mut self) -> io::Result<()> { + match cvt_null!(mnl_nlmsg_put_header_check(self.as_raw_mut() as *mut _ as *mut c_void, + self.buf.len() as size_t)) { + Ok(_) => Ok(()), + Err(e) => Err(e), + } + } + /// reserve and prepare room for an extra header /// /// # Arguments @@ -563,10 +571,20 @@ impl <'a> Nlmsg <'a> { pub fn put_extra_header(&mut self, size: usize) -> &'a mut T { unsafe { &mut(*(mnl_nlmsg_put_extra_header(self.as_raw_mut(), size as usize) as *mut T)) } } + pub fn put_extra_header_check(&mut self, size: usize) -> io::Result<&'a mut T> { + cvt_null!(mnl_nlmsg_put_extra_header_check(self.as_raw_mut(), + self.buf.len(), + size as usize) as *mut T) + } pub fn put_sized_header(&mut self) -> &'a mut T { unsafe { &mut(*(mnl_nlmsg_put_extra_header(self.as_raw_mut(), size_of::()) as *mut T)) } } + pub fn put_sized_header_check(&mut self) -> io::Result<&'a mut T> { + cvt_null!(mnl_nlmsg_put_extra_header_check(self.as_raw_mut(), + self.buf.len() as size_t, + size_of::()) as *mut T) + } pub fn ok(&self, len: isize) -> bool { unsafe { mnl_nlmsg_ok(self.as_raw_ref(), len as c_int) } diff --git a/src/nlmsg_ext.c b/src/nlmsg_ext.c index dcde3a5..21580e2 100644 --- a/src/nlmsg_ext.c +++ b/src/nlmsg_ext.c @@ -22,7 +22,7 @@ EXPORT_SYMBOL(mnl_nlmsg_put_header_check); struct nlmsghdr *mnl_nlmsg_put_header_check(void *buf, size_t buflen) { - if (MNL_NLMSG_HDRLEN < buflen) { + if (buflen < MNL_NLMSG_HDRLEN) { errno = EINVAL; return NULL; } @@ -31,7 +31,7 @@ struct nlmsghdr *mnl_nlmsg_put_header_check(void *buf, size_t buflen) } /** - * mnl_nlmsg_put_extra_header - reserve and prepare room for an extra header + * mnl_nlmsg_put_extra_header_check - reserve and prepare room for an extra header * \param nlh pointer to Netlink header * \param buflen size of buffer which stores the message * \param size size of the extra header that we want to put diff --git a/tests/lib.rs b/tests/lib.rs index f522cc9..6a75fc8 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1148,3 +1148,27 @@ fn nlmsg_batch_iterator() { } } } + +#[test] +fn nlmsg_put_extra_header_check() { + let mut buf = [0u8; 32]; + let mut nlh = mnl::Nlmsg::new(&mut buf[..]).unwrap(); + { + assert!(nlh.put_extra_header_check::(16).is_ok()); + } + { + assert!(nlh.put_extra_header_check::(16).is_err()); + } +} + +#[test] +fn nlmsg_put_sized_header_check() { + let mut buf = [0u8; 32]; + let mut nlh = mnl::Nlmsg::new(&mut buf[..]).unwrap(); + { + assert!(nlh.put_sized_header_check::().is_ok()); + } + { + assert!(nlh.put_sized_header_check::().is_err()); + } +} From 8603ce73b5071915efa7d2a7663999d511c94ba6 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Mon, 29 May 2017 12:43:37 +0900 Subject: [PATCH 14/27] mnl: returns Result instead of Option What is the idiomatic way to return an error from a function with no result if successful? https://stackoverflow.com/questions/36878044/what-is-the-idiomatic-way-to-return-an-error-from-a-function-with-no-result-if-s --- src/lib.rs | 6 +++--- tests/lib.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 14d7052..61f321d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -965,10 +965,10 @@ impl <'a> Nlmsg <'a> { /// This function adds the attribute header that identifies the beginning of /// an attribute nest. If the nested attribute cannot be added then NULL, /// otherwise valid pointer to the beginning of the nest is returned. - pub fn nest_start_check(&mut self, atype: u16) -> Option<&'a mut Attr> { + pub fn nest_start_check(&mut self, atype: u16) -> io::Result<&'a mut Attr> { let p = unsafe { mnl_attr_nest_start_check(self.as_raw_mut(), self.buf.len() as size_t, atype) }; - if p.is_null() { return None; } - unsafe { Some(&mut *p) } + if p.is_null() { return Err(io::Error::from_raw_os_error(libc::EINVAL)); } + unsafe { Ok(&mut *p) } } /// end an attribute nest diff --git a/tests/lib.rs b/tests/lib.rs index 6a75fc8..da81dbd 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -764,12 +764,12 @@ fn nlmsg_nest_start_check() { { buf = vec![0u8; 19]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.nest_start_check(0x123).is_none()); + assert!(nlh.nest_start_check(0x123).is_err()); } { buf = vec![0u8; 20]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - if let Some(attr) = nlh.nest_start_check(0x123) { + if let Ok(attr) = nlh.nest_start_check(0x123) { assert!(*nlh.nlmsg_len == linux::netlink::NLMSG_LENGTH(linux::netlink::NLA_HDRLEN() as u32)); assert!(attr.nla_len == 0); // will update after _end assert!(attr.nla_type & linux::netlink::NLA_F_NESTED != 0); From dbfe5569117c6e12c108fd4a731c53a9f2351975 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Tue, 30 May 2017 07:43:00 +0900 Subject: [PATCH 15/27] mnl: put check returns Result instead of bool same as previous --- src/lib.rs | 43 +++++++++++++++++++------------- tests/lib.rs | 70 ++++++++++++++++++++++++++-------------------------- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 61f321d..caefe03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,15 @@ macro_rules! cvt_cbret { } ) } +macro_rules! cvt_put_check { + ($f:expr) => ( { + match unsafe { $f } { + true => Ok(()), + false => Err(io::Error::from_raw_os_error(libc::EINVAL)), + } + } ) +} + pub const ALIGNTO: u32 = 4; #[allow(non_snake_case)] pub fn ALIGN(len: u32) -> u32 { @@ -830,9 +839,9 @@ impl <'a> Nlmsg <'a> { /// message (nlmsg_len) by adding the size (header + payload) of the new /// attribute. The function returns true if the attribute could be added /// to the message, otherwise false is returned. - pub fn put_check(&mut self, atype: u16, data: &T) -> bool { - unsafe { mnl_attr_put_check(self.as_raw_mut(), self.buf.len() as size_t, atype, - size_of_val(data), data as *const T as *const c_void) } + pub fn put_check(&mut self, atype: u16, data: &T) -> io::Result<()> { + cvt_put_check!(mnl_attr_put_check(self.as_raw_mut(), self.buf.len() as size_t, atype, + size_of_val(data), data as *const T as *const c_void)) } /// mnl_attr_put_u8_check - add 8-bit unsigned int attribute to netlink message @@ -846,8 +855,8 @@ impl <'a> Nlmsg <'a> { /// message (nlmsg_len) by adding the size (header + payload) of the new /// attribute. The function returns true if the attribute could be added /// to the message, otherwise false is returned. - pub fn put_u8_check(&mut self, atype: u16, data: u8) -> bool { - unsafe { mnl_attr_put_u8_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data) } + pub fn put_u8_check(&mut self, atype: u16, data: u8) -> io::Result<()> { + cvt_put_check!(mnl_attr_put_u8_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } /// add 16-bit unsigned int attribute to netlink message @@ -863,8 +872,8 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u16_check(&mut self, atype: u16, data: u16) -> bool { - unsafe { mnl_attr_put_u16_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data) } + pub fn put_u16_check(&mut self, atype: u16, data: u16) -> io::Result<()> { + cvt_put_check!(mnl_attr_put_u16_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } /// add 32-bit unsigned int attribute to netlink message @@ -880,8 +889,8 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u32_check(&mut self, atype: u16, data: u32) -> bool { - unsafe { mnl_attr_put_u32_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data) } + pub fn put_u32_check(&mut self, atype: u16, data: u32) -> io::Result<()> { + cvt_put_check!(mnl_attr_put_u32_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } /// add 64-bit unsigned int attribute to netlink message @@ -897,8 +906,8 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u64_check(&mut self, atype: u16, data: u64) -> bool { - unsafe { mnl_attr_put_u64_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data) } + pub fn put_u64_check(&mut self, atype: u16, data: u64) -> io::Result<()> { + cvt_put_check!(mnl_attr_put_u64_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } /// add string attribute to netlink message @@ -914,11 +923,11 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_str_check(&mut self, atype: u16, data: &str) -> bool { + pub fn put_str_check(&mut self, atype: u16, data: &str) -> io::Result<()> { let cs = CString::new(data).unwrap(); - unsafe { + cvt_put_check!( mnl_attr_put_str_check(self.as_raw_mut(), self.buf.len() as size_t, atype, cs.as_ptr()) - } + ) } /// add string attribute to netlink message @@ -935,11 +944,11 @@ impl <'a> Nlmsg <'a> { /// message (nlmsg_len) by adding the size (header + payload) of the new /// attribute. The function returns true if the attribute could be added /// to the message, otherwise false is returned. - pub fn put_strz_check(&mut self, atype: u16, data: &str) -> bool { + pub fn put_strz_check(&mut self, atype: u16, data: &str) -> io::Result<()> { let cs = CString::new(data).unwrap(); - unsafe { + cvt_put_check!( mnl_attr_put_strz_check(self.as_raw_mut(), self.buf.len() as size_t, atype, cs.as_ptr()) - } + ) } /// start an attribute nest diff --git a/tests/lib.rs b/tests/lib.rs index da81dbd..8edbb1e 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -460,7 +460,7 @@ fn nlmsg_put_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_check(123, &std::u64::MAX)); + assert!(nlh.put_check(123, &std::u64::MAX).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -475,14 +475,14 @@ fn nlmsg_put_check() { { let mut buf = vec![0u8; 39]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_check(123, &std::u64::MAX)); - assert!(!nlh.put_check(234, &std::u64::MAX)); + assert!(nlh.put_check(123, &std::u64::MAX).is_ok()); + assert!(nlh.put_check(234, &std::u64::MAX).is_err()); } { let mut buf = vec![0u8; 40]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_check(123, &std::u64::MAX)); - assert!(nlh.put_check(234, &std::u64::MAX)); + assert!(nlh.put_check(123, &std::u64::MAX).is_ok()); + assert!(nlh.put_check(234, &std::u64::MAX).is_ok()); } } @@ -492,7 +492,7 @@ fn nlmsg_put_u8_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u8_check(12, 34)); + assert!(nlh.put_u8_check(12, 34).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -506,16 +506,16 @@ fn nlmsg_put_u8_check() { { let mut buf = vec![0u8; 31]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u8_check(12, 34)); - assert!(!nlh.put_u8_check(56, 78)); + assert!(nlh.put_u8_check(12, 34).is_ok()); + assert!(nlh.put_u8_check(56, 78).is_err()); } buf = vec![0u8; 32]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u8_check(12, 34)); + assert!(nlh.put_u8_check(12, 34).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u8_check(56, 78)); + assert!(nlh.put_u8_check(56, 78).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 56); @@ -531,7 +531,7 @@ fn nlmsg_put_u16_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u16_check(1234, 5678)); + assert!(nlh.put_u16_check(1234, 5678).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -545,16 +545,16 @@ fn nlmsg_put_u16_check() { { let mut buf = vec![0u8; 31]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u16_check(1234, 5678)); - assert!(!nlh.put_u16_check(9012, 3456)); + assert!(nlh.put_u16_check(1234, 5678).is_ok()); + assert!(nlh.put_u16_check(9012, 3456).is_err()); } let mut buf = vec![0u8; 32]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u16_check(1234, 5678)); + assert!(nlh.put_u16_check(1234, 5678).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u16_check(9012, 3456)); + assert!(nlh.put_u16_check(9012, 3456).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 9012); @@ -570,7 +570,7 @@ fn nlmsg_put_u32_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u32_check(1234, 56789012)); + assert!(nlh.put_u32_check(1234, 56789012).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -584,16 +584,16 @@ fn nlmsg_put_u32_check() { { let mut buf = vec![0u8; 31]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u32_check(1234, 56789012)); - assert!(!nlh.put_u32_check(3456, 78901234)); + assert!(nlh.put_u32_check(1234, 56789012).is_ok()); + assert!(nlh.put_u32_check(3456, 78901234).is_err()); } buf = vec![0u8; 32]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u32_check(1234, 56789012)); + assert!(nlh.put_u32_check(1234, 56789012).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u32_check(3456, 78901234)); + assert!(nlh.put_u32_check(3456, 78901234).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 3456); @@ -609,7 +609,7 @@ fn nlmsg_put_u64_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u64_check(1234, 0x567890abcdef0123)); + assert!(nlh.put_u64_check(1234, 0x567890abcdef0123).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -623,16 +623,16 @@ fn nlmsg_put_u64_check() { { let mut buf = vec![0u8; 39]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u64_check(1234, 0x567890abcdef0123)); - assert!(!nlh.put_u64_check(4567, 0x890abcdef0123456)); + assert!(nlh.put_u64_check(1234, 0x567890abcdef0123).is_ok()); + assert!(nlh.put_u64_check(4567, 0x890abcdef0123456).is_err()); } buf = vec![0u8; 40]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u64_check(1234, 0x567890abcdef0123)); + assert!(nlh.put_u64_check(1234, 0x567890abcdef0123).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u64_check(4567, 0x890abcdef0123456)); + assert!(nlh.put_u64_check(4567, 0x890abcdef0123456).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 4567); @@ -650,7 +650,7 @@ fn nlmsg_put_str_check() { let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_str_check(1234, s1)); + assert!(nlh.put_str_check(1234, s1).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32)); let attr = nlh.payload::(); @@ -666,8 +666,8 @@ fn nlmsg_put_str_check() { { let mut buf = vec![0u8; 51]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_str_check(1234, s1)); - assert!(!nlh.put_str_check(5678, s2)); + assert!(nlh.put_str_check(1234, s1).is_ok()); + assert!(nlh.put_str_check(5678, s2).is_err()); } buf = vec![0u8; 52]; @@ -676,10 +676,10 @@ fn nlmsg_put_str_check() { let attr_len2 = linux::netlink::NLA_HDRLEN() + (b2.len() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_str_check(1234, s1)); + assert!(nlh.put_str_check(1234, s1).is_ok()); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; - assert!(nlh.put_str_check(5678, s2)); + assert!(nlh.put_str_check(5678, s2).is_ok()); assert!(attr.nla_len == attr_len2); assert!(attr.nla_type == 5678); @@ -698,7 +698,7 @@ fn nlmsg_put_strz_check() { let mut nlmsg_len = mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_strz_check(1234, s1)); + assert!(nlh.put_strz_check(1234, s1).is_ok()); assert!(*nlh.nlmsg_len == nlmsg_len); let attr = nlh.payload::(); @@ -715,8 +715,8 @@ fn nlmsg_put_strz_check() { let mut buf = vec![0u8; 51]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_strz_check(1234, s1)); - assert!(!nlh.put_strz_check(5678, s2)); + assert!(nlh.put_strz_check(1234, s1).is_ok()); + assert!(nlh.put_strz_check(5678, s2).is_err()); } let b2 = s2.as_bytes(); // .len() == 10 @@ -728,10 +728,10 @@ fn nlmsg_put_strz_check() { { set_buf(&mut buf, attr_tail, 0xffu8); let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_strz_check(1234, s1)); + assert!(nlh.put_strz_check(1234, s1).is_ok()); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; - assert!(nlh.put_strz_check(5678, s2)); + assert!(nlh.put_strz_check(5678, s2).is_ok()); assert!(*nlh.nlmsg_len == nlmsg_len); assert!(attr.nla_len == attr_len2); From e181f1be441bf722b2c8e8f6c78235c166cc2d35 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Tue, 30 May 2017 08:28:10 +0900 Subject: [PATCH 16/27] mnl: update next to use buf slice length --- src/lib.rs | 14 +++++++++----- tests/lib.rs | 6 +++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index caefe03..dbc0361 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -599,11 +599,15 @@ impl <'a> Nlmsg <'a> { unsafe { mnl_nlmsg_ok(self.as_raw_ref(), len as c_int) } } - pub fn next<'b: 'a>(&'b mut self, len: isize) -> (io::Result, isize) { - let mut rest = len as c_int; - let _ = unsafe { &mut(*mnl_nlmsg_next(self.as_raw_mut(), &mut rest)) }; - let u = self.buf.len() - rest as usize; - (Self::from_bytes(&mut self.buf[u..]), rest as isize) + pub fn next<'b: 'a>(&'b mut self) -> Option { + let mut rest = self.buf.len() as c_int; + let buflen = self.buf.len(); + if !self.ok(rest as isize) { + return None; + } + let _ = unsafe { mnl_nlmsg_next(self.as_raw_mut(), &mut rest) }; + // buflen has already checked by ok() + Some(Self::from_bytes(&mut self.buf[buflen - (rest as usize)..]).unwrap()) } /// perform sequence tracking diff --git a/tests/lib.rs b/tests/lib.rs index 8edbb1e..8020c6f 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -151,11 +151,11 @@ fn nlmsg_next_header() { let mut buf: Vec = repeat(0u8).take(512).collect(); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - let (next_nlh, rest) = nlh.next(512); - let nnlh = next_nlh.unwrap(); - assert!(rest == 512 - hdrlen as isize); + let mut nnlh = nlh.next().unwrap(); + assert!(nnlh.buflen() == 512 - hdrlen); assert!(*nnlh.nlmsg_len == 0); *nnlh.nlmsg_len = 0x11111111; + assert!(nnlh.next().is_none()); } assert_eq!(buf[hdrlen..(hdrlen + 4)], [0x11, 0x11, 0x11, 0x11]); } From 9381b08718139f3e0c12e9e8280f3c2a5c172250 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Tue, 30 May 2017 08:38:54 +0900 Subject: [PATCH 17/27] mnl: update ok() to use buf slice length --- src/lib.rs | 6 +++--- tests/lib.rs | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dbc0361..ba071b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -595,14 +595,14 @@ impl <'a> Nlmsg <'a> { size_of::()) as *mut T) } - pub fn ok(&self, len: isize) -> bool { - unsafe { mnl_nlmsg_ok(self.as_raw_ref(), len as c_int) } + pub fn ok(&self) -> bool { + unsafe { mnl_nlmsg_ok(self.as_raw_ref(), self.buf.len() as c_int) } } pub fn next<'b: 'a>(&'b mut self) -> Option { let mut rest = self.buf.len() as c_int; let buflen = self.buf.len(); - if !self.ok(rest as isize) { + if !self.ok() { return None; } let _ = unsafe { mnl_nlmsg_next(self.as_raw_mut(), &mut rest) }; diff --git a/tests/lib.rs b/tests/lib.rs index 8020c6f..127715f 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -139,10 +139,11 @@ fn nlmsg_put_extra_header() { #[test] fn nlmsg_ok() { let mut buf = vec![0; mnl::NLMSG_HDRLEN() as usize]; - let nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(!nlh.ok(15)); - assert!(nlh.ok(16)); - assert!(nlh.ok(17)); + let nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); + *nlh.nlmsg_len = 16; + assert!(nlh.ok()); + *nlh.nlmsg_len = 17; + assert!(!nlh.ok()); } #[test] From 4cf6ae9a421c14661ebfc8863d9a3b075506574c Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Tue, 30 May 2017 09:03:44 +0900 Subject: [PATCH 18/27] mnl: add comment for nlmsg_batch why I rewrite original --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ba071b6..43aa924 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1203,6 +1203,8 @@ impl <'a> Iterator for &'a mut NlmsgBatch { type Item = Nlmsg<'a>; fn next(&mut self) -> Option> { + // Here is why I rewrite rsmnl_nlmsg_batch_start() and + // rsmnl_nlmsg_batch_reset() using memset() let nlh = unsafe { rsmnl_nlmsg_batch_next(*self) }; if nlh.is_null() { return None; From 16b683d057e802f5afe2bee351ee101f10ae6117 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Thu, 1 Jun 2017 09:54:36 +0900 Subject: [PATCH 19/27] mnl: fix clearing memory on resetting nlmsg_batch. --- src/nlmsg_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nlmsg_ext.c b/src/nlmsg_ext.c index 21580e2..1d34dce 100644 --- a/src/nlmsg_ext.c +++ b/src/nlmsg_ext.c @@ -118,10 +118,10 @@ struct nlmsghdr *rsmnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b) if (b->overflow) { struct nlmsghdr *nlh = b->cur; memcpy(b->buf, b->cur, nlh->nlmsg_len); - memset(b->buf + nlh->nlmsg_len, 0, b->limit - nlh->nlmsg_len); b->buflen = nlh->nlmsg_len; b->cur = b->buf + b->buflen; b->overflow = false; + memset(b->buf + b->buflen, 0, b->limit - b->buflen); } else { b->buflen = 0; b->cur = b->buf; From 628722012636bb371d8332d0e2be35bd06ddac50 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Thu, 1 Jun 2017 11:26:14 +0900 Subject: [PATCH 20/27] examples: update mio crate description seems to be needed to be used from multiple example? --- examples/timerfd.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/examples/timerfd.rs b/examples/timerfd.rs index 0878be2..076dae5 100644 --- a/examples/timerfd.rs +++ b/examples/timerfd.rs @@ -112,21 +112,17 @@ impl AsRawFd for Timerfd { */ extern crate mio; -use mio::{ Ready, Poll, PollOpt, Token }; -use mio::unix::EventedFd; -use mio::event::Evented; - -impl Evented for Timerfd { - fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { - EventedFd(&self.0).register(poll, token, interest, opts) +impl mio::event::Evented for Timerfd { + fn register(&self, poll: &mio::Poll, token: mio::Token, interest: mio::Ready, opts: mio::PollOpt) -> io::Result<()> { + mio::unix::EventedFd(&self.0).register(poll, token, interest, opts) } - fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { - EventedFd(&self.0).reregister(poll, token, interest, opts) + fn reregister(&self, poll: &mio::Poll, token: mio::Token, interest: mio::Ready, opts: mio::PollOpt) -> io::Result<()> { + mio::unix::EventedFd(&self.0).reregister(poll, token, interest, opts) } - fn deregister(&self, poll: &Poll) -> io::Result<()> { - EventedFd(&self.0).deregister(poll) + fn deregister(&self, poll: &mio::Poll) -> io::Result<()> { + mio::unix::EventedFd(&self.0).deregister(poll) } } From 7d5c6209337a55024ee7b4bcac91fe71a498db13 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 08:53:10 +0900 Subject: [PATCH 21/27] mnl: fix Nlmsg iterator I entirely misunderstood. --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 43aa924..3cc6862 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1044,18 +1044,18 @@ impl <'a> Iterator for NlmsgIterator<'a> { type Item = Nlmsg<'a>; fn next(&mut self) -> Option> { - let ret = self.nlh as *const netlink::Nlmsghdr; + let ret_nlh = self.nlh as *mut _ as *mut u8; + let (ret_remaining, mut remaining) = (self.remaining, self.remaining as c_int); unsafe { if ! mnl_nlmsg_ok(self.nlh, self.remaining as c_int) { return None; } - let nlh = &mut *(mnl_nlmsg_next(self.nlh, &mut (self.remaining as c_int))); - if nlh.nlmsg_len == 0 { - return None; - } + + let nlh = &mut *(mnl_nlmsg_next(self.nlh, &mut remaining)); + self.remaining = remaining as usize; self.nlh = nlh; } - Some(Nlmsg::from_raw(ret).unwrap()) + Some(Nlmsg::from_raw_parts(ret_nlh, ret_remaining).unwrap()) } } From beeb934d290cb6febbc3144d649114bb9d0cd9cb Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 08:58:00 +0900 Subject: [PATCH 22/27] examples: epoll with zero timeout as with orginal And add one using iterator and put_ _check --- examples/netfilter/nfct-create-batch-check.rs | 140 ++++++++++++++++++ examples/netfilter/nfct-create-batch2.rs | 17 +-- examples/nfct-create-batch-check.rs | 1 + 3 files changed, 144 insertions(+), 14 deletions(-) create mode 100644 examples/netfilter/nfct-create-batch-check.rs create mode 120000 examples/nfct-create-batch-check.rs diff --git a/examples/netfilter/nfct-create-batch-check.rs b/examples/netfilter/nfct-create-batch-check.rs new file mode 100644 index 0000000..eee0f4f --- /dev/null +++ b/examples/netfilter/nfct-create-batch-check.rs @@ -0,0 +1,140 @@ +use std::io; +use std::net; +use std::os::unix::io::AsRawFd; +use std::mem::zeroed; + +extern crate libc; +extern crate time; +extern crate crslmnl as mnl; + +use mnl::linux::netlink as netlink; +use mnl::linux::netfilter::nfnetlink as nfnl; +use mnl::linux::netfilter::nfnetlink_conntrack as nfct; +use mnl::linux::netfilter::nf_conntrack_common as nfct_common; +use mnl::linux::netfilter::nf_conntrack_tcp as nfct_tcp; + +mod epoll; + +fn put_msg(nlh: &mut mnl::Nlmsg, i: u16, seq: u32) -> io::Result<()>{ + nlh.put_header(); + *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::IPCTNL_MSG_CT_NEW; + *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_CREATE + | netlink::NLM_F_EXCL | netlink::NLM_F_ACK; + *nlh.nlmsg_seq = seq; + + let nfh = try!(nlh.put_sized_header_check::()); + nfh.nfgen_family = libc::AF_INET as u8; + nfh.version = nfnl::NFNETLINK_V0; + nfh.res_id = 0; + + let mut nest1 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_ORIG)); + let mut nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_IP)); + try!(nlh.put_u32_check(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1)))); + try!(nlh.put_u32_check(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2)))); + nlh.nest_end(nest2); + + nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_PROTO)); + try!(nlh.put_u8_check(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8)); + try!(nlh.put_u16_check(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i))); + try!(nlh.put_u16_check(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025))); + nlh.nest_end(nest2); + nlh.nest_end(nest1); + + nest1 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_REPLY)); + nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_IP)); + try!(nlh.put_u32_check(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2)))); + try!(nlh.put_u32_check(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1)))); + nlh.nest_end(nest2); + + nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_PROTO)); + try!(nlh.put_u8_check(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8)); + try!(nlh.put_u16_check(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025))); + try!(nlh.put_u16_check(nfct::CTA_PROTO_DST_PORT, u16::to_be(i))); + nlh.nest_end(nest2); + nlh.nest_end(nest1); + + nest1 = try!(nlh.nest_start_check(nfct::CTA_PROTOINFO)); + nest2 = try!(nlh.nest_start_check(nfct::CTA_PROTOINFO_TCP)); + try!(nlh.put_u8_check(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT)); + nlh.nest_end(nest2); + nlh.nest_end(nest1); + + try!(nlh.put_u32_check(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED))); + try!(nlh.put_u32_check(nfct::CTA_TIMEOUT, u32::to_be(1000))); + + Ok(()) +} + +fn error_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { + let err = nlh.payload::(); + if err.error != 0 { + println!("message with seq {} has failed: {}", + nlh.nlmsg_seq, io::Error::from_raw_os_error(-err.error)); + } + mnl::CbRet::OK +} + +fn send_batch(nl: &mut mnl::Socket, b: &mut mnl::NlmsgBatch, portid: u32) { + nl.send_batch(b) + .unwrap_or_else(|errno| panic!("mnl_socket_sendto: {}", errno)); + + let rawfd = nl.as_raw_fd(); + let epoll = epoll::Epoll::create1(0) + .unwrap_or_else(|errno| panic!("epoll_create1: {}", errno)); + let event = epoll::Event::with_fd(libc::EPOLLIN as u32, rawfd); + epoll.ctl(libc::EPOLL_CTL_ADD, rawfd, event) + .unwrap_or_else(|errno| panic!("epoll_ctl: {}", errno)); + + let mut events: [epoll::Event; 1] = unsafe { zeroed() }; + let mut rcv_buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; + let ctl_cbs = [None, + None, // NLMSG_NOOP + Some(error_cb as mnl::Cb),]; // NLMSG_ERROR + loop { + let nevents = epoll.wait(&mut events[..], 0) + .unwrap_or_else(|errno| panic!("epoll_wait: {}", errno)); + if nevents == 0 { return; } + + let nrecv = nl.recvfrom(&mut rcv_buf) + .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); + let rc = mnl::cb_run2(&rcv_buf[0..nrecv], 0, portid, + None, &mut 0, &ctl_cbs[..]) + .unwrap_or_else(|errno| panic!("mnl_cb_run2: {}", errno)); + if rc == mnl::CbRet::STOP { + return; + } + } +} + +fn main() { + let nl = mnl::Socket::open(netlink::Family::NETFILTER) + .unwrap_or_else(|errno| panic!("mnl_socket_open: {}", errno)); + nl.bind(0, mnl::SOCKET_AUTOPID) + .unwrap_or_else(|errno| panic!("mnl_socket_bind: {}", errno)); + let portid = nl.portid(); + + let mut snd_buf = vec![0u8; mnl::SOCKET_BUFFER_SIZE()]; + let mut b = mnl::NlmsgBatch::new(&mut snd_buf) + .unwrap_or_else(|errno| panic!("mnl_nlmsg_batch_start: {}", errno)); + + let seq = time::now().to_timespec().sec as u32; + let mut sport = 1024u32; + 'sports: loop { + for mut nlh in &mut b { + if let Err(_) = put_msg(&mut nlh, sport as u16, seq + sport - 1024) { + break; + } + sport += 1; + if sport >= 65535 { break 'sports; } + } + send_batch(nl, b, portid); + b.reset(); + } + + if !b.is_empty() { + b.cap(); + send_batch(nl, b, portid); + } + + let _ = nl.close(); +} diff --git a/examples/netfilter/nfct-create-batch2.rs b/examples/netfilter/nfct-create-batch2.rs index 49b3f2c..065f3be 100644 --- a/examples/netfilter/nfct-create-batch2.rs +++ b/examples/netfilter/nfct-create-batch2.rs @@ -89,21 +89,10 @@ fn send_batch(nl: &mut mnl::Socket, b: &mut mnl::NlmsgBatch, portid: u32) { None, // NLMSG_NOOP Some(error_cb as mnl::Cb),]; // NLMSG_ERROR loop { - let nevents = epoll.wait(&mut events[..], 1) + let nevents = epoll.wait(&mut events[..], 0) .unwrap_or_else(|errno| panic!("epoll_wait: {}", errno)); - if nevents == 0 { - break; - } - let mut found = false; - for e in &events { - if e.fd() == rawfd { - found = true; - break; - } - } - if !found { - continue; - } + if nevents == 0 { return; } + let nrecv = nl.recvfrom(&mut rcv_buf) .unwrap_or_else(|errno| panic!("mnl_socket_recvfrom: {}", errno)); let rc = mnl::cb_run2(&rcv_buf[0..nrecv], 0, portid, diff --git a/examples/nfct-create-batch-check.rs b/examples/nfct-create-batch-check.rs new file mode 120000 index 0000000..b0bc825 --- /dev/null +++ b/examples/nfct-create-batch-check.rs @@ -0,0 +1 @@ +netfilter/nfct-create-batch-check.rs \ No newline at end of file From 0061ae8e4dbfea7eb2c15f81ee5ea3ac97c53095 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 11:40:09 +0900 Subject: [PATCH 23/27] mnl: make more safety rename put functions to added _raw suffix and remove check suffix from put check functions. e.g. put functions always checks its buf boundary. --- src/lib.rs | 46 ++++++------ tests/lib.rs | 193 +++++++++++++++++++++++++++------------------------ 2 files changed, 127 insertions(+), 112 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3cc6862..c15fceb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -531,7 +531,7 @@ impl <'a> Nlmsg <'a> { /// function returns a Netlink header structure. pub fn new(buf: &'a mut [u8]) -> io::Result { let mut nlh = try!(Self::from_bytes(buf)); - nlh.put_header(); + try!(nlh.put_header()); Ok(nlh) } @@ -555,11 +555,11 @@ impl <'a> Nlmsg <'a> { /// This function sets to zero the room that is required to put the Netlink /// header in the memory buffer passed as parameter. This function also /// initializes the nlmsg_len field to the size of the Netlink header. - pub fn put_header(&mut self) { + pub fn put_header_raw(&mut self) { unsafe { &mut(*mnl_nlmsg_put_header(self.as_raw_mut() as *mut _ as *mut c_void)); } } - pub fn put_header_check(&mut self) -> io::Result<()> { + pub fn put_header(&mut self) -> io::Result<()> { match cvt_null!(mnl_nlmsg_put_header_check(self.as_raw_mut() as *mut _ as *mut c_void, self.buf.len() as size_t)) { Ok(_) => Ok(()), @@ -577,19 +577,19 @@ impl <'a> Nlmsg <'a> { /// the nlmsg_len field. You have to invoke mnl_nlmsg_put_header() before /// you call this function. This function returns a pointer to the extra /// header. - pub fn put_extra_header(&mut self, size: usize) -> &'a mut T { + pub fn put_extra_header_raw(&mut self, size: usize) -> &'a mut T { unsafe { &mut(*(mnl_nlmsg_put_extra_header(self.as_raw_mut(), size as usize) as *mut T)) } } - pub fn put_extra_header_check(&mut self, size: usize) -> io::Result<&'a mut T> { + pub fn put_extra_header(&mut self, size: usize) -> io::Result<&'a mut T> { cvt_null!(mnl_nlmsg_put_extra_header_check(self.as_raw_mut(), self.buf.len(), size as usize) as *mut T) } - pub fn put_sized_header(&mut self) -> &'a mut T { + pub fn put_sized_header_raw(&mut self) -> &'a mut T { unsafe { &mut(*(mnl_nlmsg_put_extra_header(self.as_raw_mut(), size_of::()) as *mut T)) } } - pub fn put_sized_header_check(&mut self) -> io::Result<&'a mut T> { + pub fn put_sized_header(&mut self) -> io::Result<&'a mut T> { cvt_null!(mnl_nlmsg_put_extra_header_check(self.as_raw_mut(), self.buf.len() as size_t, size_of::()) as *mut T) @@ -746,7 +746,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put(&mut self, atype: u16, data: &T) { + pub fn put_raw(&mut self, atype: u16, data: &T) { // ???: data must be a #[repr(C)] unsafe { mnl_attr_put(self.as_raw_mut(), atype, size_of_val(data), data as *const T as *const c_void) } } @@ -759,7 +759,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u8(&mut self, atype: u16, data: u8) { + pub fn put_u8_raw(&mut self, atype: u16, data: u8) { unsafe { mnl_attr_put_u8(self.as_raw_mut(), atype, data) } } @@ -771,7 +771,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u16(&mut self, atype: u16, data: u16) { + pub fn put_u16_raw(&mut self, atype: u16, data: u16) { unsafe { mnl_attr_put_u16(self.as_raw_mut(), atype, data) } } @@ -783,7 +783,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u32(&mut self, atype: u16, data: u32) { + pub fn put_u32_raw(&mut self, atype: u16, data: u32) { unsafe { mnl_attr_put_u32(self.as_raw_mut(), atype, data) } } @@ -794,7 +794,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u64(&mut self, atype: u16, data: u64) { + pub fn put_u64_raw(&mut self, atype: u16, data: u64) { unsafe { mnl_attr_put_u64(self.as_raw_mut(), atype, data) } } @@ -806,7 +806,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_str(&mut self, atype: u16, data: &str) { + pub fn put_str_raw(&mut self, atype: u16, data: &str) { let cs = CString::new(data).unwrap(); unsafe { mnl_attr_put_str(self.as_raw_mut(), atype, cs.as_ptr()) @@ -824,7 +824,7 @@ impl <'a> Nlmsg <'a> { /// /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_strz(&mut self, atype: u16, data: &str) { + pub fn put_strz_raw(&mut self, atype: u16, data: &str) { let cs = CString::new(data).unwrap(); unsafe { mnl_attr_put_strz(self.as_raw_mut(), atype, cs.as_ptr()) @@ -843,7 +843,7 @@ impl <'a> Nlmsg <'a> { /// message (nlmsg_len) by adding the size (header + payload) of the new /// attribute. The function returns true if the attribute could be added /// to the message, otherwise false is returned. - pub fn put_check(&mut self, atype: u16, data: &T) -> io::Result<()> { + pub fn put(&mut self, atype: u16, data: &T) -> io::Result<()> { cvt_put_check!(mnl_attr_put_check(self.as_raw_mut(), self.buf.len() as size_t, atype, size_of_val(data), data as *const T as *const c_void)) } @@ -859,7 +859,7 @@ impl <'a> Nlmsg <'a> { /// message (nlmsg_len) by adding the size (header + payload) of the new /// attribute. The function returns true if the attribute could be added /// to the message, otherwise false is returned. - pub fn put_u8_check(&mut self, atype: u16, data: u8) -> io::Result<()> { + pub fn put_u8(&mut self, atype: u16, data: u8) -> io::Result<()> { cvt_put_check!(mnl_attr_put_u8_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } @@ -876,7 +876,7 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u16_check(&mut self, atype: u16, data: u16) -> io::Result<()> { + pub fn put_u16(&mut self, atype: u16, data: u16) -> io::Result<()> { cvt_put_check!(mnl_attr_put_u16_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } @@ -893,7 +893,7 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u32_check(&mut self, atype: u16, data: u32) -> io::Result<()> { + pub fn put_u32(&mut self, atype: u16, data: u32) -> io::Result<()> { cvt_put_check!(mnl_attr_put_u32_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } @@ -910,7 +910,7 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_u64_check(&mut self, atype: u16, data: u64) -> io::Result<()> { + pub fn put_u64(&mut self, atype: u16, data: u64) -> io::Result<()> { cvt_put_check!(mnl_attr_put_u64_check(self.as_raw_mut(), self.buf.len() as size_t, atype, data)) } @@ -927,7 +927,7 @@ impl <'a> Nlmsg <'a> { /// to the message, otherwise false is returned. /// This function updates the length field of the Netlink message (nlmsg_len) /// by adding the size (header + payload) of the new attribute. - pub fn put_str_check(&mut self, atype: u16, data: &str) -> io::Result<()> { + pub fn put_str(&mut self, atype: u16, data: &str) -> io::Result<()> { let cs = CString::new(data).unwrap(); cvt_put_check!( mnl_attr_put_str_check(self.as_raw_mut(), self.buf.len() as size_t, atype, cs.as_ptr()) @@ -948,7 +948,7 @@ impl <'a> Nlmsg <'a> { /// message (nlmsg_len) by adding the size (header + payload) of the new /// attribute. The function returns true if the attribute could be added /// to the message, otherwise false is returned. - pub fn put_strz_check(&mut self, atype: u16, data: &str) -> io::Result<()> { + pub fn put_strz(&mut self, atype: u16, data: &str) -> io::Result<()> { let cs = CString::new(data).unwrap(); cvt_put_check!( mnl_attr_put_strz_check(self.as_raw_mut(), self.buf.len() as size_t, atype, cs.as_ptr()) @@ -966,7 +966,7 @@ impl <'a> Nlmsg <'a> { /// #Return value /// This function always returns a valid pointer to the /// beginning of the nest. - pub fn nest_start(&mut self, atype: u16) -> &'a mut Attr { + pub fn nest_start_raw(&mut self, atype: u16) -> &'a mut Attr { unsafe { &mut *mnl_attr_nest_start(self.as_raw_mut(), atype) } } @@ -978,7 +978,7 @@ impl <'a> Nlmsg <'a> { /// This function adds the attribute header that identifies the beginning of /// an attribute nest. If the nested attribute cannot be added then NULL, /// otherwise valid pointer to the beginning of the nest is returned. - pub fn nest_start_check(&mut self, atype: u16) -> io::Result<&'a mut Attr> { + pub fn nest_start(&mut self, atype: u16) -> io::Result<&'a mut Attr> { let p = unsafe { mnl_attr_nest_start_check(self.as_raw_mut(), self.buf.len() as size_t, atype) }; if p.is_null() { return Err(io::Error::from_raw_os_error(libc::EINVAL)); } unsafe { Ok(&mut *p) } diff --git a/tests/lib.rs b/tests/lib.rs index 127715f..6b47817 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -122,13 +122,27 @@ fn nlmsg_put_header() { assert!(*nlh.nlmsg_len == 16); } +#[test] +fn nlmsg_put_extra_header_raw() { + let mut buf = vec![123 as u8; mnl::SOCKET_BUFFER_SIZE()]; + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); + { + let exthdr: &mut linux::netfilter::nfnetlink::Nfgenmsg + = nlh.put_extra_header_raw(size_of::()); + assert!(exthdr.nfgen_family == 0); + assert!(exthdr.version == 0); + assert!(exthdr.res_id == 0); + } + assert!(*nlh.nlmsg_len as usize == 16 + size_of::()); +} + #[test] fn nlmsg_put_extra_header() { let mut buf = vec![123 as u8; mnl::SOCKET_BUFFER_SIZE()]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); { let exthdr: &mut linux::netfilter::nfnetlink::Nfgenmsg - = nlh.put_extra_header(size_of::()); + = nlh.put_extra_header(size_of::()).unwrap(); assert!(exthdr.nfgen_family == 0); assert!(exthdr.version == 0); assert!(exthdr.res_id == 0); @@ -136,6 +150,7 @@ fn nlmsg_put_extra_header() { assert!(*nlh.nlmsg_len as usize == 16 + size_of::()); } + #[test] fn nlmsg_ok() { let mut buf = vec![0; mnl::NLMSG_HDRLEN() as usize]; @@ -231,12 +246,12 @@ fn nlmsg_payload_tail() { } #[test] -fn nlmsg_put() { +fn nlmsg_put_raw() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put(123, &std::u64::MAX); + nlh.put_raw(123, &std::u64::MAX); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -249,12 +264,12 @@ fn nlmsg_put() { } #[test] -fn nlmsg_put_u8() { +fn nlmsg_put_u8_raw() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u8(12, 34); + nlh.put_u8_raw(12, 34); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -268,7 +283,7 @@ fn nlmsg_put_u8() { { let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); - nlh.put_u8(56, 78); + nlh.put_u8_raw(56, 78); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); assert!(attr.nla_len == attr_len); @@ -280,12 +295,12 @@ fn nlmsg_put_u8() { } #[test] -fn nlmsg_put_u16() { +fn nlmsg_put_u16_raw() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u16(1234, 5678); + nlh.put_u16_raw(1234, 5678); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -299,7 +314,7 @@ fn nlmsg_put_u16() { { let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); - nlh.put_u16(9012, 3456); + nlh.put_u16_raw(9012, 3456); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); assert!(attr.nla_len == attr_len); @@ -311,12 +326,12 @@ fn nlmsg_put_u16() { } #[test] -fn nlmsg_put_u32() { +fn nlmsg_put_u32_raw() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u32(1234, 56789012); + nlh.put_u32_raw(1234, 56789012); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -330,7 +345,7 @@ fn nlmsg_put_u32() { { let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); - nlh.put_u32(3456, 78901234); + nlh.put_u32_raw(3456, 78901234); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); assert!(attr.nla_len == attr_len); @@ -342,12 +357,12 @@ fn nlmsg_put_u32() { } #[test] -fn nlmsg_put_u64() { +fn nlmsg_put_u64_raw() { let mut buf = vec![0u8; 512]; let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u64(1234, 0x567890abcdef0123); + nlh.put_u64_raw(1234, 0x567890abcdef0123); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -361,7 +376,7 @@ fn nlmsg_put_u64() { { let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); - nlh.put_u64(4567, 0x890abcdef0123456); + nlh.put_u64_raw(4567, 0x890abcdef0123456); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN((attr_len) as u32) * 2); assert!(attr.nla_len == attr_len); @@ -373,14 +388,14 @@ fn nlmsg_put_u64() { } #[test] -fn nlmsg_put_str() { +fn nlmsg_put_str_raw() { let mut buf = vec![0u8; 512]; let s1 = "Hello, world!"; let b1 = s1.as_bytes(); // .len() == 13 let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_str(1234, s1); + nlh.put_str_raw(1234, s1); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32)); let attr = nlh.payload::(); @@ -399,7 +414,7 @@ fn nlmsg_put_str() { let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; - nlh.put_str(5678, s2); + nlh.put_str_raw(5678, s2); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32) + mnl::ALIGN(attr_len2 as u32)); @@ -412,7 +427,7 @@ fn nlmsg_put_str() { } #[test] -fn nlmsg_put_strz() { +fn nlmsg_put_strz_raw() { let mut buf = vec![0u8; 512]; let s1 = "Hello, world!"; let b1 = s1.as_bytes(); // .len() == 13 @@ -420,7 +435,7 @@ fn nlmsg_put_strz() { let mut nlmsg_len = mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_strz(1234, s1); + nlh.put_strz_raw(1234, s1); assert!(*nlh.nlmsg_len == nlmsg_len); let attr = nlh.payload::(); @@ -443,7 +458,7 @@ fn nlmsg_put_strz() { let mut nlh = mnl::Nlmsg::from_bytes(&mut buf).unwrap(); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; - nlh.put_strz(5678, s2); + nlh.put_strz_raw(5678, s2); assert!(*nlh.nlmsg_len == nlmsg_len); assert!(attr.nla_len == attr_len2); @@ -461,7 +476,7 @@ fn nlmsg_put_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_check(123, &std::u64::MAX).is_ok()); + assert!(nlh.put(123, &std::u64::MAX).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -476,14 +491,14 @@ fn nlmsg_put_check() { { let mut buf = vec![0u8; 39]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_check(123, &std::u64::MAX).is_ok()); - assert!(nlh.put_check(234, &std::u64::MAX).is_err()); + assert!(nlh.put(123, &std::u64::MAX).is_ok()); + assert!(nlh.put(234, &std::u64::MAX).is_err()); } { let mut buf = vec![0u8; 40]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_check(123, &std::u64::MAX).is_ok()); - assert!(nlh.put_check(234, &std::u64::MAX).is_ok()); + assert!(nlh.put(123, &std::u64::MAX).is_ok()); + assert!(nlh.put(234, &std::u64::MAX).is_ok()); } } @@ -493,7 +508,7 @@ fn nlmsg_put_u8_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u8_check(12, 34).is_ok()); + assert!(nlh.put_u8(12, 34).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -507,16 +522,16 @@ fn nlmsg_put_u8_check() { { let mut buf = vec![0u8; 31]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u8_check(12, 34).is_ok()); - assert!(nlh.put_u8_check(56, 78).is_err()); + assert!(nlh.put_u8(12, 34).is_ok()); + assert!(nlh.put_u8(56, 78).is_err()); } buf = vec![0u8; 32]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u8_check(12, 34).is_ok()); + assert!(nlh.put_u8(12, 34).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u8_check(56, 78).is_ok()); + assert!(nlh.put_u8(56, 78).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 56); @@ -532,7 +547,7 @@ fn nlmsg_put_u16_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u16_check(1234, 5678).is_ok()); + assert!(nlh.put_u16(1234, 5678).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -546,16 +561,16 @@ fn nlmsg_put_u16_check() { { let mut buf = vec![0u8; 31]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u16_check(1234, 5678).is_ok()); - assert!(nlh.put_u16_check(9012, 3456).is_err()); + assert!(nlh.put_u16(1234, 5678).is_ok()); + assert!(nlh.put_u16(9012, 3456).is_err()); } let mut buf = vec![0u8; 32]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u16_check(1234, 5678).is_ok()); + assert!(nlh.put_u16(1234, 5678).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u16_check(9012, 3456).is_ok()); + assert!(nlh.put_u16(9012, 3456).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 9012); @@ -571,7 +586,7 @@ fn nlmsg_put_u32_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u32_check(1234, 56789012).is_ok()); + assert!(nlh.put_u32(1234, 56789012).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -585,16 +600,16 @@ fn nlmsg_put_u32_check() { { let mut buf = vec![0u8; 31]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u32_check(1234, 56789012).is_ok()); - assert!(nlh.put_u32_check(3456, 78901234).is_err()); + assert!(nlh.put_u32(1234, 56789012).is_ok()); + assert!(nlh.put_u32(3456, 78901234).is_err()); } buf = vec![0u8; 32]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u32_check(1234, 56789012).is_ok()); + assert!(nlh.put_u32(1234, 56789012).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u32_check(3456, 78901234).is_ok()); + assert!(nlh.put_u32(3456, 78901234).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 3456); @@ -610,7 +625,7 @@ fn nlmsg_put_u64_check() { let attr_len = linux::netlink::NLA_HDRLEN() + (size_of::() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u64_check(1234, 0x567890abcdef0123).is_ok()); + assert!(nlh.put_u64(1234, 0x567890abcdef0123).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len as u32)); let attr = nlh.payload::(); @@ -624,16 +639,16 @@ fn nlmsg_put_u64_check() { { let mut buf = vec![0u8; 39]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u64_check(1234, 0x567890abcdef0123).is_ok()); - assert!(nlh.put_u64_check(4567, 0x890abcdef0123456).is_err()); + assert!(nlh.put_u64(1234, 0x567890abcdef0123).is_ok()); + assert!(nlh.put_u64(4567, 0x890abcdef0123456).is_err()); } buf = vec![0u8; 40]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_u64_check(1234, 0x567890abcdef0123).is_ok()); + assert!(nlh.put_u64(1234, 0x567890abcdef0123).is_ok()); let attr = nlh.payload_tail::(); - assert!(nlh.put_u64_check(4567, 0x890abcdef0123456).is_ok()); + assert!(nlh.put_u64(4567, 0x890abcdef0123456).is_ok()); assert!(attr.nla_len == attr_len); assert!(attr.nla_type == 4567); @@ -651,7 +666,7 @@ fn nlmsg_put_str_check() { let attr_len1 = linux::netlink::NLA_HDRLEN() + (b1.len() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_str_check(1234, s1).is_ok()); + assert!(nlh.put_str(1234, s1).is_ok()); assert!(*nlh.nlmsg_len == mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32)); let attr = nlh.payload::(); @@ -667,8 +682,8 @@ fn nlmsg_put_str_check() { { let mut buf = vec![0u8; 51]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_str_check(1234, s1).is_ok()); - assert!(nlh.put_str_check(5678, s2).is_err()); + assert!(nlh.put_str(1234, s1).is_ok()); + assert!(nlh.put_str(5678, s2).is_err()); } buf = vec![0u8; 52]; @@ -677,10 +692,10 @@ fn nlmsg_put_str_check() { let attr_len2 = linux::netlink::NLA_HDRLEN() + (b2.len() as u16); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_str_check(1234, s1).is_ok()); + assert!(nlh.put_str(1234, s1).is_ok()); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; - assert!(nlh.put_str_check(5678, s2).is_ok()); + assert!(nlh.put_str(5678, s2).is_ok()); assert!(attr.nla_len == attr_len2); assert!(attr.nla_type == 5678); @@ -699,7 +714,7 @@ fn nlmsg_put_strz_check() { let mut nlmsg_len = mnl::NLMSG_HDRLEN() + mnl::ALIGN(attr_len1 as u32); { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_strz_check(1234, s1).is_ok()); + assert!(nlh.put_strz(1234, s1).is_ok()); assert!(*nlh.nlmsg_len == nlmsg_len); let attr = nlh.payload::(); @@ -716,8 +731,8 @@ fn nlmsg_put_strz_check() { let mut buf = vec![0u8; 51]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_strz_check(1234, s1).is_ok()); - assert!(nlh.put_strz_check(5678, s2).is_err()); + assert!(nlh.put_strz(1234, s1).is_ok()); + assert!(nlh.put_strz(5678, s2).is_err()); } let b2 = s2.as_bytes(); // .len() == 10 @@ -729,10 +744,10 @@ fn nlmsg_put_strz_check() { { set_buf(&mut buf, attr_tail, 0xffu8); let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.put_strz_check(1234, s1).is_ok()); + assert!(nlh.put_strz(1234, s1).is_ok()); let attr = nlh.payload_tail::(); bi = *nlh.nlmsg_len as isize; - assert!(nlh.put_strz_check(5678, s2).is_ok()); + assert!(nlh.put_strz(5678, s2).is_ok()); assert!(*nlh.nlmsg_len == nlmsg_len); assert!(attr.nla_len == attr_len2); @@ -749,7 +764,7 @@ fn nlmsg_nest_start() { let mut buf = vec![0u8; 512]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - let attr = nlh.nest_start(0x123); + let attr = nlh.nest_start_raw(0x123); assert!(*nlh.nlmsg_len == linux::netlink::NLMSG_LENGTH(linux::netlink::NLA_HDRLEN() as u32)); assert!(attr.nla_len == 0); // will update after _end @@ -765,12 +780,12 @@ fn nlmsg_nest_start_check() { { buf = vec![0u8; 19]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - assert!(nlh.nest_start_check(0x123).is_err()); + assert!(nlh.nest_start(0x123).is_err()); } { buf = vec![0u8; 20]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - if let Ok(attr) = nlh.nest_start_check(0x123) { + if let Ok(attr) = nlh.nest_start(0x123) { assert!(*nlh.nlmsg_len == linux::netlink::NLMSG_LENGTH(linux::netlink::NLA_HDRLEN() as u32)); assert!(attr.nla_len == 0); // will update after _end assert!(attr.nla_type & linux::netlink::NLA_F_NESTED != 0); @@ -787,9 +802,9 @@ fn nlmsg_nest_end() { let mut buf = vec![0u8; 512]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - let attr = nlh.nest_start(0x123); - nlh.put_u8(0x4567, 0x89); - nlh.put_u64(0xabcd, 0xef01234567890abc); + let attr = nlh.nest_start(0x123).unwrap(); + nlh.put_u8(0x4567, 0x89).unwrap(); + nlh.put_u64(0xabcd, 0xef01234567890abc).unwrap(); nlh.nest_end(attr); assert!(*nlh.nlmsg_len == 16 + 4 + 8 + 12); @@ -811,12 +826,12 @@ fn nlmsg_nest_cancel() { { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - let mut attr = nlh.nest_start(0x123); + let mut attr = nlh.nest_start(0x123).unwrap(); nlh.nest_cancel(attr); assert!(*nlh.nlmsg_len == 16); - nlh.put_u8(0x2345, 0x67); - attr = nlh.nest_start(0x234); + nlh.put_u8(0x2345, 0x67).unwrap(); + attr = nlh.nest_start(0x234).unwrap(); nlh.nest_cancel(attr); assert!(*nlh.nlmsg_len == 24); } @@ -841,15 +856,15 @@ fn nlmsg_parse() { let mut buf = vec![0u8; 512]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u8(1, 0x11); - nlh.put_u8(2, 0x12); - nlh.put_u8(3, 0x13); - nlh.put_u8(4, 0x14); + nlh.put_u8(1, 0x11).unwrap(); + nlh.put_u8(2, 0x12).unwrap(); + nlh.put_u8(3, 0x13).unwrap(); + nlh.put_u8(4, 0x14).unwrap(); assert!(nlh.parse(0, nlmsg_parse_cb1, &mut 1).unwrap() == mnl::CbRet::OK); } { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u8(0, 0x0); + nlh.put_u8(0, 0x0).unwrap(); assert!(nlh.parse(0, nlmsg_parse_cb1, &mut 1).is_err()); } } @@ -859,10 +874,10 @@ fn nlmsg_parse_2() { let mut buf = vec![0u8; 512]; { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u8(1, 0x11); - nlh.put_u8(2, 0x12); - nlh.put_u8(3, 0x13); - nlh.put_u8(4, 0x14); + nlh.put_u8(1, 0x11).unwrap(); + nlh.put_u8(2, 0x12).unwrap(); + nlh.put_u8(3, 0x13).unwrap(); + nlh.put_u8(4, 0x14).unwrap(); let mut data = 1; assert!(nlh.cl_parse(0, Box::new(|attr| { if attr.nla_type as u8 != data { @@ -877,7 +892,7 @@ fn nlmsg_parse_2() { } { let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u8(0, 0x0); + nlh.put_u8(0, 0x0).unwrap(); let mut data = 1; assert!(nlh.cl_parse(0, Box::new(|attr| { if attr.nla_type as u8 != data { @@ -897,10 +912,10 @@ fn nlmsg_parse_2() { fn nlmsg_attrs() { let mut buf = vec![0u8; 512]; let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); - nlh.put_u8(0, 0x10); - nlh.put_u8(1, 0x11); - nlh.put_u8(2, 0x12); - nlh.put_u8(3, 0x13); + nlh.put_u8(0, 0x10).unwrap(); + nlh.put_u8(1, 0x11).unwrap(); + nlh.put_u8(2, 0x12).unwrap(); + nlh.put_u8(3, 0x13).unwrap(); for (i, attr) in nlh.attrs(0).enumerate() { assert!(attr.nla_type == i as u16); @@ -1061,28 +1076,28 @@ fn nlmsg_cb_run4() { let b = mnl::NlmsgBatch::start(&mut *buf, 512 / 2).unwrap(); { let mut nlh = b.current_nlmsg().unwrap(); - nlh.put_header(); + nlh.put_header().unwrap(); *nlh.nlmsg_type = linux::netlink::NLMSG_NOOP; // 0x1 } let _ = b.proceed_next(); { let mut nlh = b.current_nlmsg().unwrap(); - nlh.put_header(); + nlh.put_header().unwrap(); *nlh.nlmsg_type = linux::netlink::NLMSG_ERROR; // 0x2 } let _ = b.proceed_next(); { let mut nlh = b.current_nlmsg().unwrap(); - nlh.put_header(); + nlh.put_header().unwrap(); *nlh.nlmsg_type = linux::netlink::NLMSG_DONE; // 0x3 } let _ = b.proceed_next(); { let mut nlh = b.current_nlmsg().unwrap(); - nlh.put_header(); + nlh.put_header().unwrap(); *nlh.nlmsg_type = linux::netlink::NLMSG_OVERRUN;// 0x4 } @@ -1118,7 +1133,7 @@ fn nlmsg_batch_iterator() { { let b = mnl::NlmsgBatch::new(&mut buf[..]).unwrap(); for (i, mut nlh) in b.enumerate() { - nlh.put_header(); // *nlh.nlmsg_len = 16; + nlh.put_header().unwrap(); // *nlh.nlmsg_len = 16; *nlh.nlmsg_type = i as u16; } b.cap(); @@ -1136,7 +1151,7 @@ fn nlmsg_batch_iterator() { { let b = mnl::NlmsgBatch::new(&mut buf[..]).unwrap(); for (i, mut nlh) in b.enumerate() { - nlh.put_header(); // *nlh.nlmsg_len = 16; + nlh.put_header().unwrap(); // *nlh.nlmsg_len = 16; *nlh.nlmsg_type = i as u16; } b.put_back(); @@ -1155,10 +1170,10 @@ fn nlmsg_put_extra_header_check() { let mut buf = [0u8; 32]; let mut nlh = mnl::Nlmsg::new(&mut buf[..]).unwrap(); { - assert!(nlh.put_extra_header_check::(16).is_ok()); + assert!(nlh.put_extra_header::(16).is_ok()); } { - assert!(nlh.put_extra_header_check::(16).is_err()); + assert!(nlh.put_extra_header::(16).is_err()); } } @@ -1167,9 +1182,9 @@ fn nlmsg_put_sized_header_check() { let mut buf = [0u8; 32]; let mut nlh = mnl::Nlmsg::new(&mut buf[..]).unwrap(); { - assert!(nlh.put_sized_header_check::().is_ok()); + assert!(nlh.put_sized_header::().is_ok()); } { - assert!(nlh.put_sized_header_check::().is_err()); + assert!(nlh.put_sized_header::().is_err()); } } From 1208862f82aae86bb45ad0d6d2471a760ac12ef7 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 11:42:36 +0900 Subject: [PATCH 24/27] examples: follow the previous update --- examples/genl/genl-family-get.rs | 6 +-- examples/genl/genl-family-get2.rs | 6 +-- examples/netfilter/nf-log-pnet.rs | 12 ++--- examples/netfilter/nf-log.rs | 12 ++--- examples/netfilter/nf-log2.rs | 12 ++--- examples/netfilter/nf-queue-pnet.rs | 14 +++--- examples/netfilter/nf-queue.rs | 14 +++--- examples/netfilter/nfct-create-batch-check.rs | 46 +++++++++---------- examples/netfilter/nfct-create-batch.rs | 46 +++++++++---------- examples/netfilter/nfct-create-batch2.rs | 46 +++++++++---------- examples/netfilter/nfct-daemon.rs | 6 +-- examples/netfilter/nfct-dump.rs | 2 +- examples/rtnl/rtnl-addr-dump.rs | 2 +- examples/rtnl/rtnl-link-dump.rs | 2 +- examples/rtnl/rtnl-link-dump2.rs | 2 +- examples/rtnl/rtnl-link-dump3.rs | 2 +- examples/rtnl/rtnl-link-set.rs | 4 +- examples/rtnl/rtnl-route-add.rs | 12 ++--- examples/rtnl/rtnl-route-dump.rs | 2 +- examples/rtnl/rtnl-route-dump2.rs | 2 +- 20 files changed, 125 insertions(+), 125 deletions(-) diff --git a/examples/genl/genl-family-get.rs b/examples/genl/genl-family-get.rs index ea8499c..d379d69 100644 --- a/examples/genl/genl-family-get.rs +++ b/examples/genl/genl-family-get.rs @@ -190,13 +190,13 @@ fn main() { *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let genl = nlh.put_sized_header::(); + let genl = nlh.put_sized_header::().unwrap(); genl.cmd = genl::CtrlCmd::GETFAMILY as u8; genl.version = 1; - nlh.put_u16(genl::CtrlAttr::FAMILY_ID as u16, genl::GENL_ID_CTRL); + nlh.put_u16(genl::CtrlAttr::FAMILY_ID as u16, genl::GENL_ID_CTRL).unwrap(); if args.len() >= 2 { - nlh.put_strz(genl::CtrlAttr::FAMILY_NAME as u16, &args[1]); + nlh.put_strz(genl::CtrlAttr::FAMILY_NAME as u16, &args[1]).unwrap(); } else { *nlh.nlmsg_flags |= netlink::NLM_F_DUMP; } diff --git a/examples/genl/genl-family-get2.rs b/examples/genl/genl-family-get2.rs index d3d18a6..579753e 100644 --- a/examples/genl/genl-family-get2.rs +++ b/examples/genl/genl-family-get2.rs @@ -197,13 +197,13 @@ fn main() { *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let genl = nlh.put_sized_header::(); + let genl = nlh.put_sized_header::().unwrap(); genl.cmd = genl::CtrlCmd::GETFAMILY as u8; genl.version = 1; - nlh.put_u16(genl::CtrlAttr::FAMILY_ID as u16, genl::GENL_ID_CTRL); + nlh.put_u16(genl::CtrlAttr::FAMILY_ID as u16, genl::GENL_ID_CTRL).unwrap(); if args.len() >= 2 { - nlh.put_strz(genl::CtrlAttr::FAMILY_NAME as u16, &args[1]); + nlh.put_strz(genl::CtrlAttr::FAMILY_NAME as u16, &args[1]).unwrap(); } else { *nlh.nlmsg_flags |= netlink::NLM_F_DUMP; } diff --git a/examples/netfilter/nf-log-pnet.rs b/examples/netfilter/nf-log-pnet.rs index e0921ab..f8d7b3e 100644 --- a/examples/netfilter/nf-log-pnet.rs +++ b/examples/netfilter/nf-log-pnet.rs @@ -127,12 +127,12 @@ fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = libc::AF_INET as u8; nfg.version = nfnl::NFNETLINK_V0; let cmd = nful::MsgConfigCmd{command: command}; - nlh.put(nful::AttrConfig::CMD as u16, &cmd); + nlh.put(nful::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -141,13 +141,13 @@ fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = libc::AF_INET as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = qnum.to_be(); let cmd = nful::MsgConfigCmd{command: command}; - nlh.put(nful::AttrConfig::CMD as u16, &cmd); + nlh.put(nful::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -156,7 +156,7 @@ fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16 *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = qnum.to_be(); @@ -166,7 +166,7 @@ fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16 copy_mode: mode, _pad: 0, }; - nlh.put(nful::AttrConfig::MODE as u16, ¶ms); + nlh.put(nful::AttrConfig::MODE as u16, ¶ms).unwrap(); nlh } diff --git a/examples/netfilter/nf-log.rs b/examples/netfilter/nf-log.rs index 93e782c..6577f88 100644 --- a/examples/netfilter/nf-log.rs +++ b/examples/netfilter/nf-log.rs @@ -91,12 +91,12 @@ fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = libc::AF_INET as u8; nfg.version = nfnl::NFNETLINK_V0; let cmd = nful::MsgConfigCmd{command: command}; - nlh.put(nful::AttrConfig::CMD as u16, &cmd); + nlh.put(nful::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -105,13 +105,13 @@ fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = libc::AF_INET as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = qnum.to_be(); let cmd = nful::MsgConfigCmd{command: command}; - nlh.put(nful::AttrConfig::CMD as u16, &cmd); + nlh.put(nful::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -120,7 +120,7 @@ fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16 *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = qnum.to_be(); @@ -130,7 +130,7 @@ fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16 copy_mode: mode, _pad: 0, }; - nlh.put(nful::AttrConfig::MODE as u16, ¶ms); + nlh.put(nful::AttrConfig::MODE as u16, ¶ms).unwrap(); nlh } diff --git a/examples/netfilter/nf-log2.rs b/examples/netfilter/nf-log2.rs index 242afc3..4672263 100644 --- a/examples/netfilter/nf-log2.rs +++ b/examples/netfilter/nf-log2.rs @@ -92,12 +92,12 @@ fn nflog_build_cfg_pf_request<'a>(buf: &'a mut [u8], command: u8) -> mnl::Nlmsg *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = libc::AF_INET as u8; nfg.version = nfnl::NFNETLINK_V0; let cmd = nful::MsgConfigCmd{command: command}; - nlh.put(nful::AttrConfig::CMD as u16, &cmd); + nlh.put(nful::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -106,13 +106,13 @@ fn nflog_build_cfg_request<'a>(buf: &'a mut [u8], command: u8, qnum: u16) -> mnl *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = libc::AF_INET as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = qnum.to_be(); let cmd = nful::MsgConfigCmd{command: command}; - nlh.put(nful::AttrConfig::CMD as u16, &cmd); + nlh.put(nful::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -121,7 +121,7 @@ fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16 *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_ULOG << 8) | nful::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = qnum.to_be(); @@ -131,7 +131,7 @@ fn nflog_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, qnum: u16 copy_mode: mode, _pad: 0, }; - nlh.put(nful::AttrConfig::MODE as u16, ¶ms); + nlh.put(nful::AttrConfig::MODE as u16, ¶ms).unwrap(); nlh } diff --git a/examples/netfilter/nf-queue-pnet.rs b/examples/netfilter/nf-queue-pnet.rs index 548c102..299c9ee 100644 --- a/examples/netfilter/nf-queue-pnet.rs +++ b/examples/netfilter/nf-queue-pnet.rs @@ -108,7 +108,7 @@ fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; @@ -117,7 +117,7 @@ fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { pf: libc::AF_INET.to_be() as u16, ..Default::default() }; - nlh.put(nfq::AttrConfig::CMD as u16, &cmd); + nlh.put(nfq::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -127,7 +127,7 @@ fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> m *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = queue_num.to_be(); @@ -137,7 +137,7 @@ fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> m pf: libc::AF_INET.to_be() as u16, ..Default::default() }; - nlh.put(nfq::AttrConfig::CMD as u16, &cmd); + nlh.put(nfq::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -147,13 +147,13 @@ fn nfq_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, queue_num: *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = queue_num.to_be(); let params = nfq::MsgConfigParams { copy_range: range.to_be(), copy_mode: mode }; - nlh.put(nfq::AttrConfig::PARAMS as u16, ¶ms); + nlh.put(nfq::AttrConfig::PARAMS as u16, ¶ms).unwrap(); nlh } @@ -162,7 +162,7 @@ fn nfq_build_verdict<'a>(buf: &'a mut [u8], id: u32, queue_num: u16, verd: u32) let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::VERDICT as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = queue_num.to_be(); diff --git a/examples/netfilter/nf-queue.rs b/examples/netfilter/nf-queue.rs index e611dc2..4e15afa 100644 --- a/examples/netfilter/nf-queue.rs +++ b/examples/netfilter/nf-queue.rs @@ -80,7 +80,7 @@ fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; @@ -89,7 +89,7 @@ fn nfq_build_cfg_pf_request<'a>(buf: &'a mut[u8], command: u8) -> mnl::Nlmsg { pf: libc::AF_INET.to_be() as u16, ..Default::default() }; - nlh.put(nfq::AttrConfig::CMD as u16, &cmd); + nlh.put(nfq::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -99,7 +99,7 @@ fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> m *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = queue_num.to_be(); @@ -109,7 +109,7 @@ fn nfq_build_cfg_request<'a>(buf: &'a mut[u8], command: u8, queue_num: u16) -> m pf: libc::AF_INET.to_be() as u16, ..Default::default() }; - nlh.put(nfq::AttrConfig::CMD as u16, &cmd); + nlh.put(nfq::AttrConfig::CMD as u16, &cmd).unwrap(); nlh } @@ -119,13 +119,13 @@ fn nfq_build_cfg_params<'a>(buf: &'a mut [u8], mode: u8, range: u32, queue_num: *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::CONFIG as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = queue_num.to_be(); let params = nfq::MsgConfigParams { copy_range: range.to_be(), copy_mode: mode }; - nlh.put(nfq::AttrConfig::PARAMS as u16, ¶ms); + nlh.put(nfq::AttrConfig::PARAMS as u16, ¶ms).unwrap(); nlh } @@ -134,7 +134,7 @@ fn nfq_build_verdict<'a>(buf: &'a mut [u8], id: u32, queue_num: u16, verd: u32) let mut nlh = mnl::Nlmsg::new(buf).unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_QUEUE << 8) | nfq::MsgTypes::VERDICT as u16; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST; - let nfg = nlh.put_sized_header::(); + let nfg = nlh.put_sized_header::().unwrap(); nfg.nfgen_family = 0; // libc::AF_UNSPEC as u8; nfg.version = nfnl::NFNETLINK_V0; nfg.res_id = queue_num.to_be(); diff --git a/examples/netfilter/nfct-create-batch-check.rs b/examples/netfilter/nfct-create-batch-check.rs index eee0f4f..48adfad 100644 --- a/examples/netfilter/nfct-create-batch-check.rs +++ b/examples/netfilter/nfct-create-batch-check.rs @@ -16,51 +16,51 @@ use mnl::linux::netfilter::nf_conntrack_tcp as nfct_tcp; mod epoll; fn put_msg(nlh: &mut mnl::Nlmsg, i: u16, seq: u32) -> io::Result<()>{ - nlh.put_header(); + nlh.put_header().unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::IPCTNL_MSG_CT_NEW; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_CREATE | netlink::NLM_F_EXCL | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let nfh = try!(nlh.put_sized_header_check::()); + let nfh = try!(nlh.put_sized_header::()); nfh.nfgen_family = libc::AF_INET as u8; nfh.version = nfnl::NFNETLINK_V0; nfh.res_id = 0; - let mut nest1 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_ORIG)); - let mut nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_IP)); - try!(nlh.put_u32_check(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1)))); - try!(nlh.put_u32_check(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2)))); + let mut nest1 = try!(nlh.nest_start(nfct::CTA_TUPLE_ORIG)); + let mut nest2 = try!(nlh.nest_start(nfct::CTA_TUPLE_IP)); + try!(nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1)))); + try!(nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2)))); nlh.nest_end(nest2); - nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_PROTO)); - try!(nlh.put_u8_check(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8)); - try!(nlh.put_u16_check(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i))); - try!(nlh.put_u16_check(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025))); + nest2 = try!(nlh.nest_start(nfct::CTA_TUPLE_PROTO)); + try!(nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8)); + try!(nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i))); + try!(nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025))); nlh.nest_end(nest2); nlh.nest_end(nest1); - nest1 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_REPLY)); - nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_IP)); - try!(nlh.put_u32_check(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2)))); - try!(nlh.put_u32_check(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1)))); + nest1 = try!(nlh.nest_start(nfct::CTA_TUPLE_REPLY)); + nest2 = try!(nlh.nest_start(nfct::CTA_TUPLE_IP)); + try!(nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2)))); + try!(nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1)))); nlh.nest_end(nest2); - nest2 = try!(nlh.nest_start_check(nfct::CTA_TUPLE_PROTO)); - try!(nlh.put_u8_check(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8)); - try!(nlh.put_u16_check(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025))); - try!(nlh.put_u16_check(nfct::CTA_PROTO_DST_PORT, u16::to_be(i))); + nest2 = try!(nlh.nest_start(nfct::CTA_TUPLE_PROTO)); + try!(nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8)); + try!(nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025))); + try!(nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(i))); nlh.nest_end(nest2); nlh.nest_end(nest1); - nest1 = try!(nlh.nest_start_check(nfct::CTA_PROTOINFO)); - nest2 = try!(nlh.nest_start_check(nfct::CTA_PROTOINFO_TCP)); - try!(nlh.put_u8_check(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT)); + nest1 = try!(nlh.nest_start(nfct::CTA_PROTOINFO)); + nest2 = try!(nlh.nest_start(nfct::CTA_PROTOINFO_TCP)); + try!(nlh.put_u8(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT)); nlh.nest_end(nest2); nlh.nest_end(nest1); - try!(nlh.put_u32_check(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED))); - try!(nlh.put_u32_check(nfct::CTA_TIMEOUT, u32::to_be(1000))); + try!(nlh.put_u32(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED))); + try!(nlh.put_u32(nfct::CTA_TIMEOUT, u32::to_be(1000))); Ok(()) } diff --git a/examples/netfilter/nfct-create-batch.rs b/examples/netfilter/nfct-create-batch.rs index 6b13414..f67ddce 100644 --- a/examples/netfilter/nfct-create-batch.rs +++ b/examples/netfilter/nfct-create-batch.rs @@ -19,51 +19,51 @@ use mnl::linux::netfilter::nf_conntrack_tcp as nfct_tcp; mod timerfd; fn put_msg(nlh: &mut mnl::Nlmsg, i: u16, seq: u32) { - nlh.put_header(); + nlh.put_header().unwrap(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::IPCTNL_MSG_CT_NEW; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_CREATE | netlink::NLM_F_EXCL | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let nfh = nlh.put_sized_header::(); + let nfh = nlh.put_sized_header::().unwrap(); nfh.nfgen_family = libc::AF_INET as u8; nfh.version = nfnl::NFNETLINK_V0; nfh.res_id = 0; - let mut nest1 = nlh.nest_start(nfct::CTA_TUPLE_ORIG); - let mut nest2 = nlh.nest_start(nfct::CTA_TUPLE_IP); - nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))); - nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))); + let mut nest1 = nlh.nest_start(nfct::CTA_TUPLE_ORIG).unwrap(); + let mut nest2 = nlh.nest_start(nfct::CTA_TUPLE_IP).unwrap(); + nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))).unwrap(); + nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))).unwrap(); nlh.nest_end(nest2); - nest2 = nlh.nest_start(nfct::CTA_TUPLE_PROTO); - nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8); - nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i)); - nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025)); + nest2 = nlh.nest_start(nfct::CTA_TUPLE_PROTO).unwrap(); + nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8).unwrap(); + nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i)).unwrap(); + nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025)).unwrap(); nlh.nest_end(nest2); nlh.nest_end(nest1); - nest1 = nlh.nest_start(nfct::CTA_TUPLE_REPLY); - nest2 = nlh.nest_start(nfct::CTA_TUPLE_IP); - nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))); - nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))); + nest1 = nlh.nest_start(nfct::CTA_TUPLE_REPLY).unwrap(); + nest2 = nlh.nest_start(nfct::CTA_TUPLE_IP).unwrap(); + nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))).unwrap(); + nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))).unwrap(); nlh.nest_end(nest2); - nest2 = nlh.nest_start(nfct::CTA_TUPLE_PROTO); - nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8); - nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025)); - nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(i)); + nest2 = nlh.nest_start(nfct::CTA_TUPLE_PROTO).unwrap(); + nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8).unwrap(); + nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025)).unwrap(); + nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(i)).unwrap(); nlh.nest_end(nest2); nlh.nest_end(nest1); - nest1 = nlh.nest_start(nfct::CTA_PROTOINFO); - nest2 = nlh.nest_start(nfct::CTA_PROTOINFO_TCP); - nlh.put_u8(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT); + nest1 = nlh.nest_start(nfct::CTA_PROTOINFO).unwrap(); + nest2 = nlh.nest_start(nfct::CTA_PROTOINFO_TCP).unwrap(); + nlh.put_u8(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT).unwrap(); nlh.nest_end(nest2); nlh.nest_end(nest1); - nlh.put_u32(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED)); - nlh.put_u32(nfct::CTA_TIMEOUT, u32::to_be(1000)); + nlh.put_u32(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED)).unwrap(); + nlh.put_u32(nfct::CTA_TIMEOUT, u32::to_be(1000)).unwrap(); } fn error_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { diff --git a/examples/netfilter/nfct-create-batch2.rs b/examples/netfilter/nfct-create-batch2.rs index 065f3be..c33c2f3 100644 --- a/examples/netfilter/nfct-create-batch2.rs +++ b/examples/netfilter/nfct-create-batch2.rs @@ -16,51 +16,51 @@ use mnl::linux::netfilter::nf_conntrack_tcp as nfct_tcp; mod epoll; fn put_msg(nlh: &mut mnl::Nlmsg, i: u16, seq: u32) { - nlh.put_header(); + nlh.put_header_raw(); *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::IPCTNL_MSG_CT_NEW; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_CREATE | netlink::NLM_F_EXCL | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let nfh = nlh.put_sized_header::(); + let nfh = nlh.put_sized_header_raw::(); nfh.nfgen_family = libc::AF_INET as u8; nfh.version = nfnl::NFNETLINK_V0; nfh.res_id = 0; - let mut nest1 = nlh.nest_start(nfct::CTA_TUPLE_ORIG); - let mut nest2 = nlh.nest_start(nfct::CTA_TUPLE_IP); - nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))); - nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))); + let mut nest1 = nlh.nest_start_raw(nfct::CTA_TUPLE_ORIG); + let mut nest2 = nlh.nest_start_raw(nfct::CTA_TUPLE_IP); + nlh.put_u32_raw(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))); + nlh.put_u32_raw(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))); nlh.nest_end(nest2); - nest2 = nlh.nest_start(nfct::CTA_TUPLE_PROTO); - nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8); - nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i)); - nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025)); + nest2 = nlh.nest_start_raw(nfct::CTA_TUPLE_PROTO); + nlh.put_u8_raw(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8); + nlh.put_u16_raw(nfct::CTA_PROTO_SRC_PORT, u16::to_be(i)); + nlh.put_u16_raw(nfct::CTA_PROTO_DST_PORT, u16::to_be(1025)); nlh.nest_end(nest2); nlh.nest_end(nest1); - nest1 = nlh.nest_start(nfct::CTA_TUPLE_REPLY); - nest2 = nlh.nest_start(nfct::CTA_TUPLE_IP); - nlh.put_u32(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))); - nlh.put_u32(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))); + nest1 = nlh.nest_start_raw(nfct::CTA_TUPLE_REPLY); + nest2 = nlh.nest_start_raw(nfct::CTA_TUPLE_IP); + nlh.put_u32_raw(nfct::CTA_IP_V4_SRC, u32::from(net::Ipv4Addr::new(2, 2, 2, 2))); + nlh.put_u32_raw(nfct::CTA_IP_V4_DST, u32::from(net::Ipv4Addr::new(1, 1, 1, 1))); nlh.nest_end(nest2); - nest2 = nlh.nest_start(nfct::CTA_TUPLE_PROTO); - nlh.put_u8(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8); - nlh.put_u16(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025)); - nlh.put_u16(nfct::CTA_PROTO_DST_PORT, u16::to_be(i)); + nest2 = nlh.nest_start_raw(nfct::CTA_TUPLE_PROTO); + nlh.put_u8_raw(nfct::CTA_PROTO_NUM, libc::IPPROTO_TCP as u8); + nlh.put_u16_raw(nfct::CTA_PROTO_SRC_PORT, u16::to_be(1025)); + nlh.put_u16_raw(nfct::CTA_PROTO_DST_PORT, u16::to_be(i)); nlh.nest_end(nest2); nlh.nest_end(nest1); - nest1 = nlh.nest_start(nfct::CTA_PROTOINFO); - nest2 = nlh.nest_start(nfct::CTA_PROTOINFO_TCP); - nlh.put_u8(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT); + nest1 = nlh.nest_start_raw(nfct::CTA_PROTOINFO); + nest2 = nlh.nest_start_raw(nfct::CTA_PROTOINFO_TCP); + nlh.put_u8_raw(nfct::CTA_PROTOINFO_TCP_STATE, nfct_tcp::TCP_CONNTRACK_SYN_SENT); nlh.nest_end(nest2); nlh.nest_end(nest1); - nlh.put_u32(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED)); - nlh.put_u32(nfct::CTA_TIMEOUT, u32::to_be(1000)); + nlh.put_u32_raw(nfct::CTA_STATUS, u32::to_be(nfct_common::IPS_CONFIRMED)); + nlh.put_u32_raw(nfct::CTA_TIMEOUT, u32::to_be(1000)); } fn error_cb(nlh: mnl::Nlmsg, _: &mut u8) -> mnl::CbRet { diff --git a/examples/netfilter/nfct-daemon.rs b/examples/netfilter/nfct-daemon.rs index 2c2e3ba..3b0f84b 100644 --- a/examples/netfilter/nfct-daemon.rs +++ b/examples/netfilter/nfct-daemon.rs @@ -251,14 +251,14 @@ fn main() { *nlh.nlmsg_type = (nfnl::NFNL_SUBSYS_CTNETLINK << 8) | nfct::IPCTNL_MSG_CT_GET_CTRZERO; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; - let nfh = nlh.put_sized_header::(); + let nfh = nlh.put_sized_header::().unwrap(); nfh.nfgen_family = libc::AF_INET as u8; nfh.version = nfnl::NFNETLINK_V0; nfh.res_id = 0; // Filter by mark: We only want to dump entries whose mark is zero - nlh.put_u32(nfct::CTA_MARK, 0u32.to_be()); - nlh.put_u32(nfct::CTA_MARK_MASK, 0xffffffffu32.to_be()); + nlh.put_u32(nfct::CTA_MARK, 0u32.to_be()).unwrap(); + nlh.put_u32(nfct::CTA_MARK_MASK, 0xffffffffu32.to_be()).unwrap(); let mut hmap = HashMap::>::new(); diff --git a/examples/netfilter/nfct-dump.rs b/examples/netfilter/nfct-dump.rs index ef4bdb4..29f6034 100644 --- a/examples/netfilter/nfct-dump.rs +++ b/examples/netfilter/nfct-dump.rs @@ -257,7 +257,7 @@ fn main() { *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let nfh = nlh.put_sized_header::(); + let nfh = nlh.put_sized_header::().unwrap(); nfh.nfgen_family = libc::AF_INET as u8; nfh.version = nfnl::NFNETLINK_V0; nfh.res_id = 0; diff --git a/examples/rtnl/rtnl-addr-dump.rs b/examples/rtnl/rtnl-addr-dump.rs index adfd06a..ecdd682 100644 --- a/examples/rtnl/rtnl-addr-dump.rs +++ b/examples/rtnl/rtnl-addr-dump.rs @@ -92,7 +92,7 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_GETADDR; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let rt = nlh.put_sized_header::(); + let rt = nlh.put_sized_header::().unwrap(); if args[1] == "inet" { rt.rtgen_family = AF_INET as u8; } else if args[1] == "inet6" { diff --git a/examples/rtnl/rtnl-link-dump.rs b/examples/rtnl/rtnl-link-dump.rs index 32d9423..f10adf5 100644 --- a/examples/rtnl/rtnl-link-dump.rs +++ b/examples/rtnl/rtnl-link-dump.rs @@ -101,7 +101,7 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_GETLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let rt = nlh.put_sized_header::(); + let rt = nlh.put_sized_header::().unwrap(); rt.rtgen_family = AF_PACKET as u8; nl.send_nlmsg(&nlh) diff --git a/examples/rtnl/rtnl-link-dump2.rs b/examples/rtnl/rtnl-link-dump2.rs index 28c4a4b..fd1d8f7 100644 --- a/examples/rtnl/rtnl-link-dump2.rs +++ b/examples/rtnl/rtnl-link-dump2.rs @@ -72,7 +72,7 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_GETLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let rt = nlh.put_sized_header::(); + let rt = nlh.put_sized_header::().unwrap(); rt.rtgen_family = AF_PACKET as u8; nl.send_nlmsg(&nlh) diff --git a/examples/rtnl/rtnl-link-dump3.rs b/examples/rtnl/rtnl-link-dump3.rs index 8be93e4..6602456 100644 --- a/examples/rtnl/rtnl-link-dump3.rs +++ b/examples/rtnl/rtnl-link-dump3.rs @@ -69,7 +69,7 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_GETLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let rt = nlh.put_sized_header::(); + let rt = nlh.put_sized_header::().unwrap(); rt.rtgen_family = AF_PACKET as u8; nl.send_nlmsg(&nlh) diff --git a/examples/rtnl/rtnl-link-set.rs b/examples/rtnl/rtnl-link-set.rs index e748e39..088d14d 100644 --- a/examples/rtnl/rtnl-link-set.rs +++ b/examples/rtnl/rtnl-link-set.rs @@ -51,12 +51,12 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_NEWLINK; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let ifm = nlh.put_sized_header::(); + let ifm = nlh.put_sized_header::().unwrap(); ifm.ifi_family = 0; // no libc::AF_UNSPEC; ifm.ifi_change = change; ifm.ifi_flags = flags; - nlh.put_str(if_link::IFLA_IFNAME, &args[1]); + nlh.put_str(if_link::IFLA_IFNAME, &args[1]).unwrap(); let my_stdout = StdoutRawFd::Dummy; nlh.fprintf(&my_stdout, size_of::()); diff --git a/examples/rtnl/rtnl-route-add.rs b/examples/rtnl/rtnl-route-add.rs index fa3dfe6..19165e0 100644 --- a/examples/rtnl/rtnl-route-add.rs +++ b/examples/rtnl/rtnl-route-add.rs @@ -103,7 +103,7 @@ Example: {} eth0 10.0.1.12 32 10.0.1.11 *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_CREATE | netlink::NLM_F_ACK; *nlh.nlmsg_seq = seq; - let rtm = nlh.put_sized_header::(); + let rtm = nlh.put_sized_header::().unwrap(); rtm.rtm_family = family as u8; rtm.rtm_dst_len = prefix as u8; rtm.rtm_src_len = 0; @@ -122,20 +122,20 @@ Example: {} eth0 10.0.1.12 32 10.0.1.11 match dst { IpAddr::V4(addr) => nlh.put_u32(rtnetlink::RTA_DST, - unsafe { transmute::<[u8; 4], u32>(addr.octets()) }), + unsafe { transmute::<[u8; 4], u32>(addr.octets()) }).unwrap(), IpAddr::V6(addr) => nlh.put(rtnetlink::RTA_DST, - &unsafe { transmute::<[u16; 8], in6_addr>(addr.segments()) }), + &unsafe { transmute::<[u16; 8], in6_addr>(addr.segments()) }).unwrap(), } - nlh.put_u32(rtnetlink::RTA_OIF, iface); + nlh.put_u32(rtnetlink::RTA_OIF, iface).unwrap(); if let Some(nh) = gw { match nh { IpAddr::V4(addr) => nlh.put_u32(rtnetlink::RTA_GATEWAY, - unsafe { transmute::<[u8; 4], u32>(addr.octets()) }), + unsafe { transmute::<[u8; 4], u32>(addr.octets()) }).unwrap(), IpAddr::V6(addr) => nlh.put(rtnetlink::RTA_GATEWAY, - &unsafe { transmute::<[u16; 8], in6_addr>(addr.segments()) }), + &unsafe { transmute::<[u16; 8], in6_addr>(addr.segments()) }).unwrap(), } } nl.send_nlmsg(&nlh) diff --git a/examples/rtnl/rtnl-route-dump.rs b/examples/rtnl/rtnl-route-dump.rs index f338f53..3aa6709 100644 --- a/examples/rtnl/rtnl-route-dump.rs +++ b/examples/rtnl/rtnl-route-dump.rs @@ -272,7 +272,7 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_GETROUTE; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let rtm = nlh.put_sized_header::(); + let rtm = nlh.put_sized_header::().unwrap(); if args[1] == "inet" { rtm.rtm_family = libc::AF_INET as u8; } else if args[1] == "inet6" { diff --git a/examples/rtnl/rtnl-route-dump2.rs b/examples/rtnl/rtnl-route-dump2.rs index 0b2073d..e97a3f5 100644 --- a/examples/rtnl/rtnl-route-dump2.rs +++ b/examples/rtnl/rtnl-route-dump2.rs @@ -276,7 +276,7 @@ fn main() { *nlh.nlmsg_type = rtnetlink::RTM_GETROUTE; *nlh.nlmsg_flags = netlink::NLM_F_REQUEST | netlink::NLM_F_DUMP; *nlh.nlmsg_seq = seq; - let rtm = nlh.put_sized_header::(); + let rtm = nlh.put_sized_header::().unwrap(); if args[1] == "inet" { rtm.rtm_family = libc::AF_INET as u8; } else if args[1] == "inet6" { From 360dac778d3151632960751ac117a174316cc67e Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 16:20:17 +0900 Subject: [PATCH 25/27] mnl: introduce Nlmsg::payload_bytes() payload_offset_bytes and payload_tail_bytes might also be needed. --- src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index c15fceb..5a48dcc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -657,6 +657,15 @@ impl <'a> Nlmsg <'a> { unsafe { &mut(*(mnl_nlmsg_get_payload(self.as_raw_mut()) as *mut T)) } } + pub fn payload_bytes(&mut self) -> &'a [u8] { + unsafe { + std::slice::from_raw_parts_mut( + mnl_nlmsg_get_payload(self.as_raw_mut()) as *mut u8, + self.payload_len(), + ) + } + } + /// get a pointer to the payload of the message /// /// # Arguments From 217afd175cdf8082e42c07f505204e8a75b52efe Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 16:24:43 +0900 Subject: [PATCH 26/27] mnl: rename parse_payload() to parse_attrs() And add cl_parse_attrs. --- src/lib.rs | 9 +++++++-- tests/lib.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5a48dcc..b94e961 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1466,11 +1466,16 @@ extern fn attr_parse_cb2(attr: *const netlink::Nlattr, data: *mut c_void) -> c_i /// # Return values /// This function propagates the return value of the callback, which can be /// MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP. -pub fn parse_payload<'a, T: 'a + ?Sized>(payload: &[u8], payload_len: usize, cb: AttrCb<'a, T>, data: &mut T) -> io::Result<(CbRet)> { +pub fn parse_attrs<'a, T: 'a + ?Sized>(payload: &[u8], cb: AttrCb<'a, T>, data: &mut T) -> io::Result<(CbRet)> { let mut cbdata = AttrCbData{ cb: cb, data: data }; let pdata = &mut cbdata as *mut _ as *mut c_void; cvt_cbret!(mnl_attr_parse_payload(payload.as_ptr() as *const c_void, - payload_len as size_t, attr_parse_cb::, pdata)) + payload.len() as size_t, attr_parse_cb::, pdata)) +} + +pub fn cl_parse_attrs<'a>(payload: &[u8], cb: Box CbRet>) -> io::Result<(CbRet)> { + cvt_cbret!(mnl_attr_parse_payload(payload.as_ptr() as *const c_void, payload.len() as size_t, + attr_parse_cb2, Box::into_raw(Box::new(cb)) as *mut c_void)) } extern fn nlmsg_parse_cb(nlh: *const netlink::Nlmsghdr, data: *mut c_void) -> c_int { diff --git a/tests/lib.rs b/tests/lib.rs index 6b47817..c2e2647 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1188,3 +1188,49 @@ fn nlmsg_put_sized_header_check() { assert!(nlh.put_sized_header::().is_err()); } } + +fn attr_cb1(attr: &mnl::Attr, data: &mut u16) -> mnl::CbRet { + if attr.nla_type < *data { + return mnl::CbRet::OK; + } + mnl::CbRet::ERROR +} + +#[test] +fn attr_parse_attrs() { + let mut buf = [0u8; 512]; + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); + for i in 0..4 { + nlh.put_u8(i as u16, i).unwrap(); + } + + assert!(mnl::parse_attrs(nlh.payload_bytes(), attr_cb1, &mut 4u16).unwrap() == mnl::CbRet::OK); + assert!(mnl::parse_attrs(nlh.payload_bytes(), attr_cb1, &mut 3u16).is_err()); +} + +#[test] +fn attr_cl_parse_payload() { + let mut buf = [0u8; 512]; + let mut nlh = mnl::Nlmsg::new(&mut buf).unwrap(); + for i in 0..4 { + nlh.put_u8(i as u16, i).unwrap(); + } + + let mut data = 4; + assert!(mnl::cl_parse_attrs(nlh.payload_bytes(), + Box::new(move |attr| { + if attr.nla_type < data { + return mnl::CbRet::OK; + } + mnl::CbRet::ERROR + })).unwrap() == mnl::CbRet::OK); + + data = 3; + assert!(mnl::cl_parse_attrs(nlh.payload_bytes(), + Box::new(move |attr| { + if attr.nla_type < data { + return mnl::CbRet::OK; + } + mnl::CbRet::ERROR + })).is_err()); +} From c06cd5d670b6f74a6a3d43aea410ee5ec02321ee Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Fri, 2 Jun 2017 16:26:14 +0900 Subject: [PATCH 27/27] doc: update --- README.md | 62 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index c446f79..194092f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ crslmnl ======= -Rust wrapper of libmnl, less safe. +A Rust wrapper for libmnl. sample @@ -13,7 +13,12 @@ see examples requires -------- - * libmnl +* libmnl - C libmnl library +* Rust gcc +* for examples: + - Rust time + - Rust mio + - Rust pnet links @@ -34,7 +39,7 @@ thanks to [Shepmaster](http://stackoverflow.com/users/155423/shepmaster) comparison ---------- -| original | cgolmnl | remarks | +| original | crslmnl | remarks | | ------------------------------------- | ----------------------------- | ----------------------------- | | mnl_attr_get_type | Attr.atype | | | mnl_attr_get_len | Attr.len | | @@ -47,38 +52,44 @@ comparison | mnl_attr_validate | Attr.validate | | | mnl_attr_validate2 | Attr.validate2 | | | mnl_attr_parse | Attr.parse | | +| (add) | Attr.cl_parse | | | mnl_attr_parse_nested | Attr.parse_nested | | -| mnl_attr_parse_payload | parse_payload | | +| (add) | Attr.cl_parse_nested | | +| mnl_attr_parse_payload | parse_attrs | | +| (add) | cl_parse_attrs | | | mnl_attr_get_u8 | Attr.u8 | | | mnl_attr_get_u16 | Attr.u16 | | | mnl_attr_get_u32 | Attr.u32 | | | mnl_attr_get_u64 | Attr.u64 | | | mnl_attr_get_str | Attr.str | | | (add) | Attr.string | | -| mnl_attr_put | Nlmsg.put | | -| mnl_attr_put_u8 | Nlmsg.put_u8 | | -| mnl_attr_put_u16 | Nlmsg.put_u16 | | -| mnl_attr_put_u32 | Nlmsg.put_u32 | | -| mnl_attr_put_u64 | Nlmsg.put_u64 | | -| mnl_attr_put_str | Nlmsg.put_str | | -| mnl_attr_put_strz | Nlmsg.put_strz | | -| mnl_attr_put_check | Nlmsg.put_check | | -| mnl_attr_put_u8_check | Nlmsg.put_u8_check | | -| mnl_attr_put_u16_check | Nlmsg.put_u16_check | | -| mnl_attr_put_u32_check | Nlmsg.put_u32_check | | -| mnl_attr_put_u64_check | Nlmsg.put_u64_check | | -| mnl_attr_put_str_check | Nlmsg.put_str_check | | -| mnl_attr_put_strz_check | Nlmsg.put_strz_check | | -| mnl_attr_nest_start | Nlmsg.nest_start | | -| mnl_attr_nest_start_check | Nlmsg.nest_start_check | | +| mnl_attr_put | Nlmsg.put_raw | | +| mnl_attr_put_u8 | Nlmsg.put_u8_raw | | +| mnl_attr_put_u16 | Nlmsg.put_u16_raw | | +| mnl_attr_put_u32 | Nlmsg.put_u32_raw | | +| mnl_attr_put_u64 | Nlmsg.put_u64_raw | | +| mnl_attr_put_str | Nlmsg.put_str_raw | | +| mnl_attr_put_strz | Nlmsg.put_strz_raw | | +| mnl_attr_put_check | Nlmsg.put | | +| mnl_attr_put_u8_check | Nlmsg.put_u8 | | +| mnl_attr_put_u16_check | Nlmsg.put_u16 | | +| mnl_attr_put_u32_check | Nlmsg.put_u32 | | +| mnl_attr_put_u64_check | Nlmsg.put_u64 | | +| mnl_attr_put_str_check | Nlmsg.put_str | | +| mnl_attr_put_strz_check | Nlmsg.put_strz | | +| mnl_attr_nest_start | Nlmsg.nest_start_raw | | +| mnl_attr_nest_start_check | Nlmsg.nest_start | | | mnl_attr_nest_end | Nlmsg.nest_end | | | mnl_attr_nest_cancel | Nlmsg.nest_cancel | | | ------------------------------------- | ----------------------------- | ----------------------------- | | mnl_nlmsg_size | Nlmsg::size | | | mnl_nlmsg_get_payload_len | Nlmsg.payload_len | | | mnl_nlmsg_put_header | Nlmsg::new | | -| mnl_nlmsg_put_header | Nlmsg.put_header | | -| mnl_nlmsg_put_extra_header | Nlmsg.put_extra_header | | +| mnl_nlmsg_put_header | Nlmsg.put_header_raw | | +| (add) | Nlmsg.put_header_check | | +| mnl_nlmsg_put_extra_header | Nlmsg.put_extra_header_raw | | +| (add) | Nlmsg.put_sized_header | | +| (add) | Nlmsg.put_sized_header_raw | | | (add) | Nlmsg.put_sized_header | | | mnl_nlmsg_get_paylod | Nlmsg.payload | | | mnl_nlmsg_get_paylod | Nlmsg.payload_mut | | @@ -102,7 +113,9 @@ comparison | mnl_nlmsg_batch_is_empty | NlmsgBatch.is_empty | | | ------------------------------------- | ----------------------------- | ----------------------------- | | mnl_cb_run | cb_run | | -| mnl_cb_run2 | cb_run2 | changed signature | +| mnl_cb_run2 | cb_run2 | | +| (add) | cl_run | closure instead of callback | +| (add) | cl_run2 | closure instead of callback | | ------------------------------------- | ----------------------------- | ----------------------------- | | mnl_socket_get_fd | Socket.as_raw_fd | | | mnl_socket_get_portid | Socket.portid | | @@ -120,3 +133,6 @@ comparison | ------------------------------------- | ----------------------------- | ----------------------------- | | mnl_attr_for_each | Nlmsg.attrs | | | mnl_attr_for_each_nested | Attr.nesteds | | +| ------------------------------------- | ----------------------------- | ----------------------------- | +| (add) | NlmsgIterator | | +| (add) | Iterator for NlmsgBatch | |