#rust #nftables
Вопрос:
Я использую nftnl-rs для построения таблицы правил nftables с большим успехом. Но теперь я хочу знать, есть ли уже таблица с таким же именем в системе. Я нашел две функции в nftnl-rs nftnl/src/table.rs
, которые, похоже, точно созданы для этого : get_tables_nlmsg() и get_tables_cb(). Однако я не смог успешно их использовать. get_tables_cb()
в строке документа говорится, что он был создан для обработки вывода первого , но get_tables_nlmsg()
возвращает a Vec<u8>
, по-видимому, содержащий адрес памяти созданного nlmsghdr, в то get_tables_cb()
время как принимает an amp;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: amp;mut HashSet<CString> = amp;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(amp;amp;buffer, amp;mut tables);
println!("{:?}", tables);
Ok(())
}
rustc жалуется , что он ожидал amp;nlmsghdr
и получил amp;amp;*const nlmsghdr
«а», и я не смог бросить первое во второе. Я просмотрел исходный код и примеры, не видя появления этого случая приведения. Перескакивая назад и вперед в источнике, я обнаружил, что часть Номикона говорит о непрозрачных структурах, которые , похоже, применимы nlmsghdr
, но также не решают мою проблему. На самом деле я немного запутался с объявлением функции :
pub fn get_tables_cb(header: amp;libc::nlmsghdr, tables: amp;mut HashSet<CString>) -> libc::c_int
Если *const libc::nlmsghdr
это чужеродная Структура, то что, черт возьми, может amp;libc::nlmsghdr
быть ? Может быть, где-то в источнике nftnl-rs есть опечатка ?
Комментарии:
1. Вы пробовали отправлять сообщение, сгенерированное с
get_tables_nlmsg
помощью сокета netfilter, и анализировать результат с помощьюget_tables_cb
?2. Я попробую это сделать. Вы случайно не Ls256 в Вики-арке ? Недавно я скопировал статью о NanoPi_M1 из упомянутой вики на свою страницу пользователя, потому что они угрожают удалить ее как нецелевое использование.
3. Я не они, но рад, что смог помочь!
Ответ №1:
Используя предложение Coder-256, можно найти mnl::cb_run2()
в дочернем пакете mnl-rs, который может использоваться nftnl::tables::get_tables_cb()
в качестве обратного вызова при получении пакета netlink. Поскольку пакеты netlink могут быть многопакетными, если данные слишком велики, чтобы поместиться в одном NlMsg, вероятно, можно было бы использовать его следующим образом :
use std::collections::HashSet;
use mnl;
use nftnl;
fn dump_tables() -> Result<(), Box<dyn std::error::Error>> {
let seq = 0;
let tables = amp;mut HashSet::new();
let mut buffer = nftnl::table::get_tables_nlmsg(seq);
let socket = mnl::Socket::new(mnl::Bus::Netfilter)?;
socket.send(amp;buffer)?;
// Answer may be multi-packed, loop over what we get.
loop {
let chars_written = socket.recv(amp;mut *buffer)?;
if chars_written == 0 { break; }
let message = amp;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(())
}
Я должен признаться, что до сих пор не знаю, что amp;libc::nlmsghdr
именно означает, как и зачем его строить ; я с радостью приму любой ответ, который сможет прояснить этот момент.