netlink_rust/
generic.rs

1use std::fmt;
2use std::io;
3use std::io::{Read, Seek, Write};
4
5use std::convert::{From, Into};
6
7use errors::Result;
8
9use core;
10use core::{Attribute, Sendable, MessageFlags, MessageMode,
11    NativeRead, NativeWrite, ConvertFrom};
12
13extended_enum!(FamilyId, u16,
14    Control => 16,
15    VirtualFileSystemDiskQuota => 17,
16    Raid => 18,
17);
18
19extended_enum_default!(Command, u8,
20    Unspecified => 0,
21    NewFamily => 1,
22    DelFamily => 2,
23    GetFamily => 3,
24    NewOps => 4,
25    DelOps => 5,
26    GetOps => 6,
27    NewMulticastGroup => 7,
28    DelMulticastGroup => 8,
29    GetMulticastGroup => 9,
30);
31
32extended_enum_default!(AttributeId, u16,
33    Unspecified => 0,
34    FamilyId => 1,
35    FamilyName => 2,
36    Version => 3,
37    HeaderSize => 4,
38    MaximumAttributes => 5,
39    Operations => 6,
40    MulticastGroups => 7,
41);
42
43extended_enum_default!(OperationAttributeId, u16,
44    Unspecified => 0,
45    Id => 1,
46    Flags => 2,
47);
48
49extended_enum_default!(MulticastAttributeId, u16,
50    Unspecified => 0,
51    Name => 1,
52    Id => 2,
53);
54
55pub struct Message {
56    pub family: u16,
57    pub command: u8,
58    pub version: u8,
59    pub flags: MessageFlags,
60    pub attributes: Vec<Attribute>,
61}
62
63impl Message {
64    pub fn new<F: Into<u16>, C: Into<u8>, M: Into<MessageFlags>>
65        (family: F, command: C, mode: M) -> Message {
66        return Message {
67            family: family.into(),
68            command: command.into(),
69            version: 1u8,
70            flags: mode.into(),
71            attributes: vec!(),
72            };
73    }
74
75    pub fn parse<R: Read + Seek>(reader: &mut R) -> Result<Message> {
76        let command = u8::read(reader)?;
77        let version = u8::read(reader)?;
78        let _ = u16::read(reader)?;
79        let attributes = core::parse_attributes(reader);
80        Ok(Message {
81            family: 0xffff,
82            command: command,
83            version: version,
84            flags: MessageFlags::from_bits_truncate(0),
85            attributes: attributes,
86            })
87    }
88
89    pub fn family(&self) -> u16 { self.family.clone().into() }
90
91    pub fn set_flags(&mut self, flags: MessageFlags) { self.flags = flags; }
92
93    pub fn append_attribute(&mut self, attr: Attribute)
94    {
95        self.attributes.push(attr);
96    }
97}
98
99impl Sendable for Message {
100    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
101        self.command.write(writer)?;
102        self.version.write(writer)?;
103        0u16.write(writer)?;
104        for attr in self.attributes.iter() {
105            attr.write(writer)?;
106        }
107        Ok(())
108    }
109    fn message_type(&self) -> u16 { self.family.clone().into() }
110    fn query_flags(&self) -> MessageFlags { self.flags }
111}
112
113impl fmt::Display for Message {
114    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115        write!(f,
116            "Family: {} Command: {} Version: {} Flags: {:x} Attribute Count: {}",
117            self.family, self.command, self.version, self.flags.bits(),
118            self.attributes.len()
119        )
120    }
121}
122
123/// Netlink generic Multi-cast group
124/// 
125/// Contains identifier, name for a Netlink multi-cast group.
126pub struct MultiCastGroup {
127    pub id: u32,
128    pub name: String,
129}
130
131impl MultiCastGroup {
132    fn from_bytes(bytes: &[u8]) -> Result<MultiCastGroup>
133    {
134        let attributes = core::parse_attributes(&mut io::Cursor::new(bytes));
135        let mut group_name = String::new();
136        let mut group_id = None;
137        for attribute in attributes {
138            match MulticastAttributeId::from(attribute.identifier) {
139                MulticastAttributeId::Unspecified => {}
140                MulticastAttributeId::Id => {
141                    group_id = attribute.as_u32().ok();
142                }
143                MulticastAttributeId::Name => {
144                    group_name = attribute.as_string()?;
145                }
146            }
147        }
148        if let Some(id) = group_id {
149            return Ok(MultiCastGroup {
150                id: id,
151                name: group_name,
152            });
153        }
154        Err(io::Error::new(io::ErrorKind::InvalidData, "").into())
155    }
156}
157
158impl fmt::Display for MultiCastGroup {
159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160        write!(f, "MultiCast Group: {} Name: {}", self.id, self.name)
161    }
162}
163
164/// Netlink generic family
165/// 
166/// Contains identifier, name and multi-cast groups for a Netlink family.
167pub struct Family {
168    pub id: u16,
169    pub name: String,
170    pub multicast_groups: Vec<MultiCastGroup>,
171}
172
173impl Family {
174    fn from_message(message: Message) -> Result<Family>
175    {
176        let mut family_name = String::new();
177        let mut family_id = 0u16;
178        let mut groups = vec![];
179        for attr in message.attributes {
180            match AttributeId::from(attr.identifier) {
181                AttributeId::Unspecified => {}
182                AttributeId::FamilyName => {
183                    family_name = attr.as_string()?;
184                }
185                AttributeId::FamilyId => {
186                    family_id = attr.as_u16()?;
187                }
188                AttributeId::MulticastGroups => {
189                    let mcs_attributes = core::parse_attributes(&mut io::Cursor::new(attr.as_bytes()));
190                    for mcs_attr in mcs_attributes {
191                        groups.push(MultiCastGroup::from_bytes(&mcs_attr.as_bytes())?);
192                    }
193                }
194                _ => {}
195            }
196        }
197        if family_id > 0 {
198            return Ok(Family { id: family_id, name: family_name, multicast_groups: groups });
199        }
200        Err(io::Error::new(io::ErrorKind::NotFound, "Family Not Found").into())
201    }
202}
203
204impl fmt::Display for Family {
205    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
206        write!(f, "Generic Family: {} Name: {}", self.id, self.name)
207    }
208}
209
210pub fn get_generic_families(socket: &mut core::Socket) -> Result<Vec<Family>>
211{
212    {
213        let tx_msg = Message::new(FamilyId::Control, Command::GetFamily, MessageMode::Dump);
214        socket.send_message(&tx_msg)?;
215    }
216    let messages = socket.receive_messages()?;
217    let mut families = vec![];
218    for message in messages {
219        match message {
220            core::Message::Data(m) => {
221                if FamilyId::from(m.header.identifier) == FamilyId::Control {
222                    let msg = Message::parse(&mut io::Cursor::new(m.data))?;
223                    families.push(Family::from_message(msg)?);
224                }
225            },
226            core::Message::Acknowledge => (),
227            core::Message::Done => { break; }
228        }
229    }
230    return Ok(families)
231}
232
233pub fn get_generic_family(socket: &mut core::Socket, name: &str) -> Result<Family>
234{
235    {
236        let mut tx_msg = Message::new(FamilyId::Control, Command::GetFamily, MessageMode::Acknowledge);
237        tx_msg.attributes.push(Attribute::new_string(AttributeId::FamilyName, name));
238        socket.send_message(&tx_msg)?;
239    }
240    loop {
241        let messages = socket.receive_messages()?;
242        if messages.is_empty() {
243            break;
244        }
245        for message in messages {
246            match message {
247                core::Message::Data(m) => {
248                    if FamilyId::convert_from(m.header.identifier) == Some(FamilyId::Control) {
249                        let msg = Message::parse(&mut io::Cursor::new(m.data))?;
250                        let family = Family::from_message(msg)?;
251                        if family.name == name {
252                            return Ok(family);
253                        }
254                    }
255                },
256                _ => (),
257            }
258        }
259    }
260    Err(io::Error::new(io::ErrorKind::NotFound, "Generic family not found").into())
261}