1use libc;
4
5use crate::core::{
6 pack_vec, Attribute, ConvertFrom, MessageFlags, NativePack, NativeUnpack, SendMessage,
7};
8use crate::errors::{NetlinkError, NetlinkErrorKind, Result};
9
10extended_enum!(
11 FamilyId, u16,
13 NewLink => 16,
15 DeleteLink => 17,
17 GetLink => 18,
19 SetLink => 19,
21);
22
23extended_enum_default!(AddressFamilyAttribute, u16,
24 Unspecified => 0,
25 Address => 1,
26 Broadcast => 2,
27 InterfaceName => 3,
28 MTU => 4,
29 Link => 5,
30 QDisc => 6,
31 Stats => 7,
32 Cost => 8,
33 Priority => 9,
34 Master => 10,
35 WirelessExtension => 11,
36 ProtocolInformation => 12,
37 TransmitQueueLength => 13,
38 Map => 14,
39 Weight => 15,
40 OperationState => 16,
41 LinkMode => 17,
42 LinkInfo => 18,
43 NetworkNameSpacePid => 19,
44 InterfaceAlias => 20,
45 NumberVf => 21,
46 VfInfoList => 22,
47 Stats64 => 23,
48 VfPorts => 24,
49 PortSelf => 25,
50 AfSpecification => 26,
51 Group => 27,
52 NetworkNameSpaceFileDescriptor => 28,
53 ExtendedMask => 29,
54 PromiscuityCount => 30,
55 TransmitQueueCount => 31,
56 ReceiveQueueCount => 32,
57 Carrier => 33,
58 PhysPortId => 34,
59 CarrierChanges => 35,
60 PhysSwitchId => 36,
61 LinkNetworkNameSpaceId => 37,
62 PhysPortName => 38,
63 ProtocolDown => 39,
64 GsoMaximumSegs => 40,
65 GsoMaximumSize => 41,
66 Padding => 42,
67 Xdp => 43,
68 Event => 44,
69 NewNetworkNameSpaceId => 45,
70 InterfaceNetworkNameSpaceId => 46,
71);
72
73pub struct Message {
75 pub family: u16,
77 pub attributes: Vec<Attribute>,
79}
80
81impl Message {
82 pub fn new<F: Into<u16>>(family: F) -> Message {
84 return Message {
85 family: family.into(),
86 attributes: vec![],
87 };
88 }
89}
90
91impl SendMessage for Message {
92 fn pack(&self, data: &mut [u8]) -> Result<usize> {
93 let kind: u8 = libc::AF_PACKET as u8;
94 let slice = kind.pack(data)?;
95 let size = pack_vec(slice, &self.attributes)?;
96 Ok(size + 1)
97 }
98 fn message_type(&self) -> u16 {
99 self.family
100 }
101 fn query_flags(&self) -> MessageFlags {
102 MessageFlags::REQUEST | MessageFlags::DUMP
103 }
104}
105
106pub struct InterfaceInformationMessage {
110 pub family: u8,
112 pub kind: u16,
114 pub index: i32,
116 pub flags: u32,
118 pub change: u32,
120 pub attributes: Vec<Attribute>,
122}
123
124impl InterfaceInformationMessage {
125 pub fn unpack(data: &[u8]) -> Result<(usize, InterfaceInformationMessage)> {
127 if data.len() < 16 {
128 return Err(NetlinkError::new(NetlinkErrorKind::NotEnoughData).into());
129 }
130 let family = u8::unpack_unchecked(&data[0..]);
131 let kind = u16::unpack_unchecked(&data[2..]);
133 let index = i32::unpack_unchecked(&data[4..]);
134 let flags = u32::unpack_unchecked(&data[8..]);
135 let change = u32::unpack_unchecked(&data[12..]);
136 let (used, attributes) = Attribute::unpack_all(&data[16..]);
137 Ok((
138 used + 16,
139 InterfaceInformationMessage {
140 family: family,
141 kind: kind,
142 index: index,
143 flags: flags,
144 change: change,
145 attributes: attributes,
146 },
147 ))
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154 use crate::core::{Protocol, Socket};
155
156 #[test]
157 fn route_get_link() {
158 let mut socket = Socket::new(Protocol::Route).unwrap();
159 let msg = Message::new(FamilyId::GetLink);
160 socket.send_message(&msg).unwrap();
161 for m in socket.receive_messages().unwrap() {
162 assert_eq!(m.header.identifier, FamilyId::NewLink);
163 }
164 }
165}