| // 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 = |
| <NetlinkMessage<GenlMessage<GenlCtrl>>>::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"); |
| } |
| } |