// SPDX-License-Identifier: MIT use netlink_packet_core::{NetlinkMessage, NetlinkPayload, NLM_F_REQUEST}; use netlink_packet_generic::{ ctrl::{nlas::GenlCtrlAttrs, GenlCtrl, GenlCtrlCmd}, GenlMessage, }; use netlink_sys::{protocols::NETLINK_GENERIC, Socket, SocketAddr}; #[test] fn query_family_id() { let mut socket = Socket::new(NETLINK_GENERIC).unwrap(); socket.bind_auto().unwrap(); socket.connect(&SocketAddr::new(0, 0)).unwrap(); let mut genlmsg = GenlMessage::from_payload(GenlCtrl { cmd: GenlCtrlCmd::GetFamily, nlas: vec![GenlCtrlAttrs::FamilyName("nlctrl".to_owned())], }); genlmsg.finalize(); let mut nlmsg = NetlinkMessage::from(genlmsg); nlmsg.header.flags = NLM_F_REQUEST; nlmsg.finalize(); println!("Buffer length: {}", nlmsg.buffer_len()); let mut txbuf = vec![0u8; nlmsg.buffer_len()]; nlmsg.serialize(&mut txbuf); socket.send(&txbuf, 0).unwrap(); let (rxbuf, _addr) = socket.recv_from_full().unwrap(); let rx_packet = >>::deserialize(&rxbuf).unwrap(); if let NetlinkPayload::InnerMessage(genlmsg) = rx_packet.payload { if GenlCtrlCmd::NewFamily == genlmsg.payload.cmd { let family_id = genlmsg .payload .nlas .iter() .find_map(|nla| { if let GenlCtrlAttrs::FamilyId(id) = nla { Some(*id) } else { None } }) .expect("Cannot find FamilyId attribute"); // nlctrl's family must be 0x10 assert_eq!(0x10, family_id); } else { panic!("Invalid payload type: {:?}", genlmsg.payload.cmd); } } else { panic!("Failed to get family ID"); } }