use crate::bss::Bss;
use crate::station::Station;
use crate::nl80211traits::ParseNlAttr;
use neli::consts::{NlFamily,NlmF,Nlmsg};
use neli::socket::NlSocket;
use neli::nl::Nlmsghdr;
use neli::genl::Genlmsghdr;
use crate::consts::{NL_80211_GENL_NAME, NL_80211_GENL_VERSION};
use crate::attr::Nl80211Attr;
use crate::cmd::Nl80211Cmd;
use crate::interface::Interface;
use neli::nlattr::Nlattr;
pub struct Socket {
pub sock: NlSocket,
pub family_id: u16,
}
impl Socket {
pub fn connect() -> Result<Self, neli::err::NlError> {
let family_id = {
NlSocket::new(NlFamily::Generic, true)?
.resolve_genl_family(NL_80211_GENL_NAME)?
};
let track_seq = true;
let mut nl80211sock = NlSocket::new(NlFamily::Generic, track_seq)?;
let pid = None;
let groups = None;
nl80211sock.bind(pid, groups)?;
Ok(Self {
sock: nl80211sock,
family_id: family_id,
})
}
pub fn get_interfaces_info(&mut self) -> Result<Vec<Interface>, neli::err::NlError> {
let mut interfaces = Vec::new();
let nl80211sock = &mut self.sock;
let attrs: Vec<Nlattr<Nl80211Attr, Vec<u8>>> = vec![];
let genlhdr = Genlmsghdr::new(Nl80211Cmd::CmdGetInterface, NL_80211_GENL_VERSION, attrs)?;
let nlhdr = {
let len = None;
let nl_type = self.family_id;
let flags = vec![NlmF::Request, NlmF::Dump];
let seq = None;
let pid = None;
let payload = genlhdr;
Nlmsghdr::new(len, nl_type, flags, seq, pid, payload)
};
nl80211sock.send_nl(nlhdr)?;
let mut iter = nl80211sock.iter::<Nlmsg, Genlmsghdr<Nl80211Cmd, Nl80211Attr>>();
while let Some(Ok(response)) = iter.next() {
match response.nl_type {
Nlmsg::Error => panic!("Error"),
Nlmsg::Done => break,
_ => {
let handle = response.nl_payload.get_attr_handle();
interfaces.push(Interface::default().parse(handle));
},
};
}
Ok(interfaces)
}
pub fn get_station_info(&mut self, interface_attr_if_index: &Vec<u8>) -> Result<Station, neli::err::NlError> {
let nl80211sock = &mut self.sock;
let mut attrs: Vec<Nlattr<Nl80211Attr, Vec<u8>>> = vec![];
let new_attr= Nlattr::new(None, Nl80211Attr::AttrIfindex, interface_attr_if_index.to_owned())?;
attrs.push(new_attr);
let genlhdr = Genlmsghdr::new(Nl80211Cmd::CmdGetStation, NL_80211_GENL_VERSION, attrs)?;
let nlhdr = {
let len = None;
let nl_type = self.family_id;
let flags = vec![NlmF::Request, NlmF::Dump];
let seq = None;
let pid = None;
let payload = genlhdr;
Nlmsghdr::new(len, nl_type, flags, seq, pid, payload)
};
nl80211sock.send_nl(nlhdr)?;
let mut iter = nl80211sock.iter::<Nlmsg, Genlmsghdr<Nl80211Cmd, Nl80211Attr>>();
while let Some(Ok(response)) = iter.next() {
match response.nl_type {
Nlmsg::Error => panic!("Error"),
Nlmsg::Done => break,
_ => {
let handle = response.nl_payload.get_attr_handle();
return Ok(Station::default().parse(handle));
},
};
}
return Ok(Station::default())
}
pub fn get_bss_info(&mut self, interface_attr_if_index: &Vec<u8>) -> Result<Bss, neli::err::NlError> {
let nl80211sock = &mut self.sock;
let mut attrs: Vec<Nlattr<Nl80211Attr, Vec<u8>>> = vec![];
let new_attr= Nlattr::new(None, Nl80211Attr::AttrIfindex, interface_attr_if_index.to_owned())?;
attrs.push(new_attr);
let genlhdr = Genlmsghdr::new(Nl80211Cmd::CmdGetScan, NL_80211_GENL_VERSION, attrs)?;
let nlhdr = {
let len = None;
let nl_type = self.family_id;
let flags = vec![NlmF::Request, NlmF::Dump];
let seq = None;
let pid = None;
let payload = genlhdr;
Nlmsghdr::new(len, nl_type, flags, seq, pid, payload)
};
nl80211sock.send_nl(nlhdr)?;
let mut iter = nl80211sock.iter::<Nlmsg, Genlmsghdr<Nl80211Cmd, Nl80211Attr>>();
while let Some(Ok(response)) = iter.next() {
match response.nl_type {
Nlmsg::Error => panic!("Error"),
Nlmsg::Done => break,
_ => {
let handle = response.nl_payload.get_attr_handle();
return Ok(Bss::default().parse(handle))
}
}
}
Ok(Bss::default())
}
}