首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将`&&*const libc::foreignStruct`转换为`&libc::foreignStruct`

将`&&*const libc::foreignStruct`转换为`&libc::foreignStruct`
EN

Stack Overflow用户
提问于 2021-10-08 23:00:25
回答 1查看 49关注 0票数 1

我正在使用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作为参数。

具体来说,我尝试了:

代码语言:javascript
复制
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,但也不能解决我的问题。事实上,我对函数声明有一点困惑:

代码语言:javascript
复制
pub fn get_tables_cb(header: &libc::nlmsghdr, tables: &mut HashSet<CString>) -> libc::c_int

如果*const libc::nlmsghdr是一个外来结构,那么&libc::nlmsghdr到底是什么呢?会不会是nftnl-rs的源代码中有一个拼写错误?

EN

回答 1

Stack Overflow用户

发布于 2021-10-09 17:55:23

使用Coder256的建议,可以从姊妹包mnl-rs中找到mnl::cb_run2(),它可以在接收netlink数据包时使用nftnl::tables::get_tables_cb()作为回调。由于如果数据太大而无法容纳在一个NlMsg中,netlink数据包可能会出现多个数据包,因此可能会这样使用:

代码语言:javascript
复制
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到底是什么意思,如何以及为什么要构建一个;我将很乐意接受任何能够启发这一点的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69502465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档