我正在使用nftnl-rs构建一个包含nftables规则的表,并取得了巨大的成功。但是现在我想知道系统中是否已经有同名的表。我在nftnl-rs的nftnl/src/table.rs中发现了两个函数:get_tables_nlmsg()和get_tables_cb()。get_tables_cb()的文档字符串说它是用来处理前者的输出的,但是get_tables_nlmsg()返回一个Vec<u8>,显然包含创建的nlmsghdr的内存地址,而get_tables_cb()接受一个&nlmsghdr作为参数。
具体来说,我尝试了:
use std::collections::HashSet;
use std::ffi::CString;
use nftnl{self, nftnl_sys::libc};
fn dump_tables() -> Result<(), Box<dyn std::error::Error> {
let mut tables: &mut HashSet<CString> = &mut HashSet::new();
let mut buffer = nftnl::table::get_tables_nlmsg(0);
let buffer = buffer.as_ptr() as *const libc::nlmsghdr;
nftnl::table::get_tables_cb(&&buffer, &mut tables);
println!("{:?}", tables);
Ok(())
}rustc抱怨说,它期望得到一个&nlmsghdr,并得到了一个&&*const nlmsghdr,而我无法将前者转换为后者。我浏览了源代码和示例,但没有看到这个case出现。在源码中来回跳转,我发现Nomicon中谈论opaque structs的一部分似乎适用于nlmsghdr,但也不能解决我的问题。事实上,我对函数声明有一点困惑:
pub fn get_tables_cb(header: &libc::nlmsghdr, tables: &mut HashSet<CString>) -> libc::c_int如果*const libc::nlmsghdr是一个外来结构,那么&libc::nlmsghdr到底是什么呢?会不会是nftnl-rs的源代码中有一个拼写错误?
发布于 2021-10-09 17:55:23
使用Coder256的建议,可以从姊妹包mnl-rs中找到mnl::cb_run2(),它可以在接收netlink数据包时使用nftnl::tables::get_tables_cb()作为回调。由于如果数据太大而无法容纳在一个NlMsg中,netlink数据包可能会出现多个数据包,因此可能会这样使用:
use std::collections::HashSet;
use mnl;
use nftnl;
fn dump_tables() -> Result<(), Box<dyn std::error::Error>> {
let seq = 0;
let tables = &mut HashSet::new();
let mut buffer = nftnl::table::get_tables_nlmsg(seq);
let socket = mnl::Socket::new(mnl::Bus::Netfilter)?;
socket.send(&buffer)?;
// Answer may be multi-packed, loop over what we get.
loop {
let chars_written = socket.recv(&mut *buffer)?;
if chars_written == 0 { break; }
let message = &buffer[..chars_written];
match mnl::cb_run2(message, seq, socket.portid(), nftnl::table::get_tables_cb, tables)? {
mnl::CbResult::Stop => break,
mnl::CbResult::Ok => ()
}
}
println!("{:?}", tables);
Ok(())
}我必须承认,我仍然不知道&libc::nlmsghdr到底是什么意思,如何以及为什么要构建一个;我将很乐意接受任何能够启发这一点的答案。
https://stackoverflow.com/questions/69502465
复制相似问题