nl80211_ng/
lib.rs

1#![allow(dead_code)]
2#![allow(unused_imports)]
3pub mod attr;
4pub mod channels;
5pub mod cmd;
6pub mod interface;
7pub mod ntsocket;
8pub mod phy;
9pub mod rtsocket;
10pub mod util;
11
12use attr::{Nl80211ChanWidth, Nl80211ChannelType, Nl80211Iftype, Operstate};
13use channels::{chan_to_frequency, WiFiBand};
14pub use interface::Interface;
15use ntsocket::NtSocket;
16use phy::WirelessPhy;
17use rtsocket::RtSocket;
18
19use std::collections::HashMap;
20
21pub const NL_80211_GENL_NAME: &str = "nl80211";
22pub const NL_80211_GENL_VERSION: u8 = 1;
23
24#[derive(Debug)]
25pub struct Nl80211 {
26    pub nt_socket: NtSocket,
27    pub rt_socket: RtSocket,
28    pub wirelessphys: HashMap<u32, WirelessPhy>,
29    pub interfaces: HashMap<u32, Interface>,
30}
31
32impl Nl80211 {
33    /// Creates a new instance of the Nl80211 Struct.
34    pub fn new() -> Result<Nl80211, String> {
35        let mut nt_socket: NtSocket = NtSocket::connect()?;
36        let mut rt_socket: RtSocket = RtSocket::connect()?;
37
38        let wirelessphys: HashMap<u32, phy::WirelessPhy> = nt_socket.cmd_get_all_wiphy()?;
39        let mut interfaces: HashMap<u32, Interface> = nt_socket.cmd_get_interfaces()?;
40
41        for (phy, interface) in &mut interfaces {
42            if wirelessphys.contains_key(phy) {
43                if let Some(index) = interface.index {
44                    interface.phy = wirelessphys.get(phy).cloned();
45                    interface.state = Some(rt_socket.get_interface_status(index)?);
46                }
47            }
48        }
49
50        Ok(Nl80211 {
51            nt_socket,
52            rt_socket,
53            wirelessphys,
54            interfaces,
55        })
56    }
57
58    /// Updates the interfaces and Wiphy lists of the struct.
59    fn update_interfaces(&mut self) -> Result<(), String> {
60        let wirelessphys: HashMap<u32, phy::WirelessPhy> = self.nt_socket.cmd_get_all_wiphy()?;
61        let mut interfaces: HashMap<u32, Interface> = self.nt_socket.cmd_get_interfaces()?;
62
63        for (phy, interface) in &mut interfaces {
64            if wirelessphys.contains_key(phy) {
65                if let Some(index) = interface.index {
66                    interface.phy = wirelessphys.get(phy).cloned();
67                    interface.state = Some(self.rt_socket.get_interface_status(index)?);
68                }
69            }
70        }
71        self.interfaces = interfaces;
72        self.wirelessphys = wirelessphys;
73        Ok(())
74    }
75
76    pub fn pretty_print_interfaces(&mut self) {
77        for interface in self.interfaces.values() {
78            let string = interface.pretty_print();
79            println!("{}", string);
80        }
81    }
82
83    pub fn interface(&self, idx: u32) -> Option<Interface> {
84        self.interfaces.values().find(|f| f.index == Some(idx)).cloned()
85    }
86
87    pub fn get_interfaces(&self) -> &HashMap<u32, Interface> {
88        &self.interfaces
89    }
90
91    pub fn get_wiphys(&self) -> &HashMap<u32, WirelessPhy> {
92        &self.wirelessphys
93    }
94
95    pub fn get_mut_interfaces(&mut self) -> &mut HashMap<u32, Interface> {
96        &mut self.interfaces
97    }
98
99    pub fn get_mut_wiphys(&mut self) -> &mut HashMap<u32, WirelessPhy> {
100        &mut self.wirelessphys
101    }
102
103    pub fn set_interface_monitor(&mut self, active: bool, index: u32) -> Result<(), String> {
104        self.nt_socket
105            .set_type_vec(index, Nl80211Iftype::IftypeMonitor, active)?;
106        self.update_interfaces()?;
107        Ok(())
108    }
109
110    pub fn set_interface_station(&mut self, index: u32) -> Result<(), String> {
111        self.nt_socket
112            .set_type_vec(index, Nl80211Iftype::IftypeStation, false)?;
113        self.update_interfaces()?;
114        Ok(())
115    }
116
117    pub fn set_interface_chan(&mut self, index: u32, channel: u32, band: u8) -> Result<(), String> {
118        let band = WiFiBand::from_u8(band)?;
119        self.nt_socket.set_frequency(
120            index,
121                chan_to_frequency(channel, band),
122            Nl80211ChanWidth::ChanWidth20Noht,
123            Nl80211ChannelType::ChanNoHt,
124        )?;
125        self.update_interfaces()?;
126        Ok(())
127    }
128
129    pub fn set_powersave_off(&mut self, index: u32) -> Result<(), String> {
130        self.nt_socket.set_powersave_off(
131            index,
132        )?;
133        self.update_interfaces()?;
134        Ok(())
135    }
136
137    // rtnetlink commands- all use interface index.
138
139    pub fn set_interface_up(&mut self, index: u32) -> Result<(), String> {
140        self.rt_socket.set_interface_up(index)?;
141        self.update_interfaces()?;
142        Ok(())
143    }
144
145    pub fn set_interface_down(&mut self, index: u32) -> Result<(), String> {
146        self.rt_socket.set_interface_down(index)?;
147        self.update_interfaces()?;
148        Ok(())
149    }
150
151    pub fn set_interface_mac(&mut self, index: u32, mac: &[u8; 6]) -> Result<(), String> {
152        self.rt_socket.set_interface_mac(index, mac)?;
153        self.update_interfaces()?;
154        Ok(())
155    }
156
157    pub fn set_interface_mac_random(&mut self, index: u32) -> Result<(), String> {
158        self.rt_socket.set_interface_mac_random(index)?;
159        self.update_interfaces()?;
160        Ok(())
161    }
162
163    fn get_interface_state(&mut self, index: u32) -> Result<Operstate, String> {
164        self.rt_socket.get_interface_status(index)
165    }
166}
167
168///
169///
170/// The following functions are designed to be used more independently than the Nl80211 struct, making them easier to use in multi-threaded code.
171/// They can be fired off in a "one-shot" style.
172fn get_interfaces_info() -> Result<HashMap<u32, Interface>, String> {
173    let mut nt_socket: NtSocket = NtSocket::connect()?;
174    let mut rt_socket: RtSocket = RtSocket::connect()?;
175
176    let wiphys: HashMap<u32, phy::WirelessPhy> = nt_socket.cmd_get_all_wiphy()?;
177    let mut interfaces: HashMap<u32, Interface> = nt_socket.cmd_get_interfaces()?;
178
179    for (phy, interface) in &mut interfaces {
180        if wiphys.contains_key(phy) {
181            if let Some(index) = interface.index {
182                interface.phy = wiphys.get(&phy).cloned();
183                interface.state = Some(rt_socket.get_interface_status(index)?);
184            }
185        }
186    }
187    Ok(interfaces)
188}
189
190pub fn get_interface_info_idx(interface_index: u32) -> Result<Interface, String> {
191    let mut nt_socket: NtSocket = NtSocket::connect()?;
192    let mut rt_socket: RtSocket = RtSocket::connect()?;
193
194    let wiphys: HashMap<u32, phy::WirelessPhy> = nt_socket.cmd_get_all_wiphy()?;
195    let mut interfaces: HashMap<u32, Interface> = nt_socket.cmd_get_interfaces()?;
196
197    for (phy, interface) in &mut interfaces {
198        if let Some(index) = interface.index {
199            if wiphys.contains_key(phy) {
200                interface.phy = wiphys.get(phy).cloned();
201                interface.state = Some(rt_socket.get_interface_status(index)?);
202            }
203            if index == interface_index {
204                return Ok(interface.clone());
205            }
206        }
207    }
208    Err("Interface Not Found".to_string())
209}
210
211pub fn get_interface_info_name(interface_name: &String) -> Result<Interface, String> {
212    let mut nt_socket: NtSocket = NtSocket::connect()?;
213    let mut rt_socket: RtSocket = RtSocket::connect()?;
214
215    let wiphys: HashMap<u32, phy::WirelessPhy> = nt_socket.cmd_get_all_wiphy()?;
216    let mut interfaces: HashMap<u32, Interface> = nt_socket.cmd_get_interfaces()?;
217
218    for (phy, interface) in &mut interfaces {
219        if let Some(index) = interface.index {
220            if wiphys.contains_key(phy) {
221                interface.phy = wiphys.get(phy).cloned();
222                interface.state = Some(rt_socket.get_interface_status(index)?);
223            } else {
224                return Err("Phy does not exist...".to_string());
225            }
226            if &interface.name_as_string() == interface_name {
227                return Ok(interface.clone());
228            }
229        }
230    }
231    Err("Interface Not Found".to_string())
232}
233
234pub fn set_interface_monitor(interface_index: u32, active: bool) -> Result<(), String> {
235    let mut nt_socket = NtSocket::connect()?;
236    nt_socket.set_type_vec(interface_index, Nl80211Iftype::IftypeMonitor, active)?;
237    Ok(())
238}
239
240pub fn set_interface_station(interface_index: u32) -> Result<(), String> {
241    let mut nt_socket = NtSocket::connect()?;
242    nt_socket.set_type_vec(interface_index, Nl80211Iftype::IftypeStation, false)?;
243    Ok(())
244}
245
246pub fn set_interface_chan(interface_index: u32, channel: u32, band: u8) -> Result<(), String> {
247    let mut nt_socket = NtSocket::connect()?;
248    let band = WiFiBand::from_u8(band)?;
249    nt_socket.set_frequency(
250        interface_index,
251        chan_to_frequency(channel, band),
252        Nl80211ChanWidth::ChanWidth20Noht,
253        Nl80211ChannelType::ChanNoHt,
254    )?;
255    Ok(())
256}
257
258pub fn set_powersave_off(index: u32) -> Result<(), String> {
259    let mut nt_socket = NtSocket::connect()?;
260    nt_socket.set_powersave_off(
261        index,
262    )?;
263    Ok(())
264}
265
266// rtnetlink commands- all use interface index.
267
268pub fn set_interface_up(interface_index: u32) -> Result<(), String> {
269    let mut rt_socket = RtSocket::connect()?;
270    rt_socket.set_interface_up(interface_index)?;
271    Ok(())
272}
273
274pub fn set_interface_down(interface_index: u32) -> Result<(), String> {
275    let mut rt_socket = RtSocket::connect()?;
276    rt_socket.set_interface_down(interface_index)?;
277    Ok(())
278}
279
280pub fn set_interface_mac(interface_index: u32, mac: &[u8; 6]) -> Result<(), String> {
281    let mut rt_socket = RtSocket::connect()?;
282    rt_socket.set_interface_mac(interface_index, mac)?;
283    Ok(())
284}
285
286pub fn set_interface_mac_random(interface_index: u32) -> Result<(), String> {
287    let mut rt_socket = RtSocket::connect()?;
288    rt_socket.set_interface_mac_random(interface_index)?;
289    Ok(())
290}
291// This should only be called when "updating" an interface, so we won't update it after doing this.
292fn get_interface_state(interface_index: u32) -> Result<Operstate, String> {
293    let mut rt_socket = RtSocket::connect().map_err(|e| e.to_string())?;
294    rt_socket.get_interface_status(interface_index)
295}