Skip to content

Commit

Permalink
Add set interface functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ollipa committed Aug 2, 2023
1 parent f3d8f15 commit 451cbb1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ impl NlAttrType for Attribute {}
///
/// nl80211_iftype enum from:
/// https://github.com/torvalds/linux/blob/master/include/uapi/linux/nl80211.h
#[neli_enum(serialized_type = "u16")]
#[neli_enum(serialized_type = "u32")]
pub(crate) enum InterfaceType {
/// Unspecified type, driver decides.
Unspecified = 0,
Expand Down Expand Up @@ -386,8 +386,6 @@ pub(crate) enum InterfaceType {
Nan = 12,
}

impl NlAttrType for InterfaceType {}

/// Nl80211 per TXQ (transmit queue) statistics.
///
/// These attribute types are used with `Attribute.TxqStats` to get
Expand Down
3 changes: 3 additions & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub(crate) enum Command {
/// Request an interface's configuration. Either a dump request for all
/// interfaces or a specific get with a single NL80211_ATTR_IFINDEX is supported.
GetInterface = 5,
/// Set type of a virtual interface,
/// requires NL80211_ATTR_IFINDEX and NL80211_ATTR_IFTYPE.
SetInterface = 6,
NewInterface = 7,
DelInterface = 8,
Expand Down Expand Up @@ -56,6 +58,7 @@ pub(crate) enum Command {
/// reserved; not used
SetMgmtExtraIe = 30,

/// Ask the wireless core to send us its currently set regulatory domain.
GetReg = 31,

GetScan = 32,
Expand Down
21 changes: 21 additions & 0 deletions src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,27 @@ pub enum InterfaceType {
Unknown,
}

impl From<InterfaceType> for NlInterfaceType {
fn from(value: InterfaceType) -> Self {
match value {
InterfaceType::Unspecified => NlInterfaceType::Unspecified,
InterfaceType::Adhoc => NlInterfaceType::Adhoc,
InterfaceType::Station => NlInterfaceType::Station,
InterfaceType::AccessPoint => NlInterfaceType::Ap,
InterfaceType::ApVlan => NlInterfaceType::ApVlan,
InterfaceType::Wds => NlInterfaceType::Wds,
InterfaceType::Monitor => NlInterfaceType::Monitor,
InterfaceType::MeshPoint => NlInterfaceType::MeshPoint,
InterfaceType::P2pClient => NlInterfaceType::P2pClient,
InterfaceType::P2pGroupOwner => NlInterfaceType::P2pGo,
InterfaceType::P2pDevice => NlInterfaceType::P2pDevice,
InterfaceType::Ocb => NlInterfaceType::Ocb,
InterfaceType::NotNetdev => NlInterfaceType::Nan,
InterfaceType::Unknown => NlInterfaceType::Unspecified,
}
}
}

impl fmt::Display for InterfaceType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let interface_type = match self {
Expand Down
40 changes: 40 additions & 0 deletions src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ use neli::types::GenlBuffer;
use crate::reg_domain::RegulatoryDomain;
use crate::station::WirelessStation;
use crate::wiphy::PhysicalDevice;
use crate::InterfaceType;

use super::attributes::Attribute;
use super::attributes::InterfaceType as NlInterfaceType;
use super::commands::Command;
use super::interface::WirelessInterface;

Expand Down Expand Up @@ -61,6 +63,44 @@ impl NlSocket {
Ok(responses)
}

pub fn set_interface(&mut self, if_index: u32, if_type: InterfaceType) -> Result<(), NlError> {
let attrs = {
let mut attrs = GenlBuffer::new();
attrs.push(Nlattr::new(false, false, Attribute::Ifindex, if_index).unwrap());
attrs.push(
Nlattr::new(
false,
false,
Attribute::Iftype,
Into::<NlInterfaceType>::into(if_type),
)
.unwrap(),
);
attrs
};

let nl_payload =
Genlmsghdr::<Command, Attribute>::new(Command::SetInterface, NL80211_VERSION, attrs);

let msg = self.build_header(nl_payload, &[NlmF::Request, NlmF::Ack]);

self.socket.send(msg)?;
for response in self.socket.iter::<Nlmsg, Neli80211Header>(false) {
let response = response.map_err(NlError::new)?;
match response.nl_payload {
NlPayload::Err(e) => {
error!("Error when reading response: {e}");
break;
}
NlPayload::Payload(payload) => {
dbg!(&payload);
}
NlPayload::Empty | NlPayload::Ack(_) => (),
};
}
Ok(())
}

pub fn list_stations(&mut self, if_index: u32) -> Result<Vec<WirelessStation>, NlError> {
let attrs = {
let mut attrs = GenlBuffer::new();
Expand Down

0 comments on commit 451cbb1

Please sign in to comment.