neli-wifi-0.6.1/.cargo_vcs_info.json0000644000000001360000000000100127230ustar { "git": { "sha1": "741b77d049f0ad8701ae7692eef0b0b54b690a06" }, "path_in_vcs": "" }neli-wifi-0.6.1/.github/workflows/rust.yml000064400000000000000000000024071046102023000166330ustar 00000000000000on: [push, pull_request] name: Rust jobs: check: name: Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: dtolnay/rust-toolchain@stable - name: Check run: cargo check --all --all-features test: name: Test Suite runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: submodules: recursive - uses: dtolnay/rust-toolchain@stable - name: Tests run: cargo test --all --all-features fmt: name: Rustfmt runs-on: ubuntu-latest steps: - name: Get required packages run: sudo apt-get install fd-find - uses: actions/checkout@v3 with: submodules: recursive - uses: dtolnay/rust-toolchain@stable with: components: rustfmt - name: Fmt check run: rustfmt --check --edition 2021 $(fdfind -e rs) clippy: name: Clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: submodules: recursive - uses: dtolnay/rust-toolchain@stable with: components: clippy - name: Clippy check run: cargo clippy --all --all-features -- -D warnings -A unknown-lints neli-wifi-0.6.1/.gitignore000064400000000000000000000000571046102023000135050ustar 00000000000000/target **/*.rs.bk Cargo.lock /examples/target neli-wifi-0.6.1/Cargo.lock0000644000000223570000000000100107070ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "addr2line" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "backtrace" version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", ] [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "gimli" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "hermit-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "miniz_oxide" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", "windows-sys", ] [[package]] name = "neli" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" dependencies = [ "byteorder", "libc", "log", "neli-proc-macros", "tokio", ] [[package]] name = "neli-proc-macros" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" dependencies = [ "either", "proc-macro2", "quote", "serde", "syn 1.0.109", ] [[package]] name = "neli-wifi" version = "0.6.1" dependencies = [ "neli", "neli-proc-macros", "tokio", ] [[package]] name = "num_cpus" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", ] [[package]] name = "object" version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "pin-project-lite" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "proc-macro2" version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "serde" version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", "syn 2.0.31", ] [[package]] name = "socket2" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", "windows-sys", ] [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "syn" version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tokio" version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", "socket2", "tokio-macros", "windows-sys", ] [[package]] name = "tokio-macros" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", "syn 2.0.31", ] [[package]] name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" neli-wifi-0.6.1/Cargo.toml0000644000000024270000000000100107260ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "neli-wifi" version = "0.6.1" authors = [ "eonm ", "Max Verevkin ", ] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Communicate with nl80211" readme = "README.md" keywords = [ "wifi", "neli", "netlink", "nl80211", ] license = "MIT" repository = "https://github.com/MaxVerevkin/neli-wifi" [package.metadata.docs.rs] all-features = true rustdoc-args = [ "--cfg", "docsrs", ] [features] async = ["neli/async"] default = [] [lib] name = "neli_wifi" path = "src/lib.rs" [dependencies.neli] version = "0.6.0" [dependencies.neli-proc-macros] version = "0.1.0" [dev-dependencies.tokio] version = "1.0" features = [ "macros", "rt-multi-thread", ] neli-wifi-0.6.1/Cargo.toml.orig000064400000000000000000000013551046102023000144060ustar 00000000000000[package] name = "neli-wifi" version = "0.6.1" authors = ["eonm ", "Max Verevkin "] edition = "2021" description = "Communicate with nl80211" repository = "https://github.com/MaxVerevkin/neli-wifi" license = "MIT" keywords = ["wifi", "neli", "netlink", "nl80211"] [features] default = [] async = ["neli/async"] [dependencies] neli = "0.6.0" neli-proc-macros = "0.1.0" [dev-dependencies] neli-wifi = { path = ".", features = ["async"] } [dev-dependencies.tokio] version = "1.0" features = ["macros", "rt-multi-thread"] [package.metadata.docs.rs] # To build locally: # RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --no-deps --open all-features = true rustdoc-args = ["--cfg", "docsrs"] neli-wifi-0.6.1/LICENSE000064400000000000000000000020451046102023000125210ustar 00000000000000MIT License Copyright (c) 2019 Eonm Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. neli-wifi-0.6.1/README.md000064400000000000000000000003501046102023000127700ustar 00000000000000[![Latest Version](https://img.shields.io/crates/v/neli-wifi.svg)](https://crates.io/crates/neli-wifi) [![Documentation](https://docs.rs/neli-wifi/badge.svg)](https://docs.rs/neli-wifi) Rewrite of neli-wifi-0.6.1/src/async_socket.rs000064400000000000000000000117201046102023000153360ustar 00000000000000use crate::Attrs; use crate::Bss; use crate::Interface; use crate::Nl80211Attr; use crate::Nl80211Cmd; use crate::Socket; use crate::Station; use crate::NL_80211_GENL_VERSION; use neli::err::DeError; use neli::consts::genl::{CtrlAttr, CtrlCmd}; use neli::consts::{nl::GenlId, nl::NlmF, nl::NlmFFlags, nl::Nlmsg}; use neli::err::NlError; use neli::genl::{Genlmsghdr, Nlattr}; use neli::nl::{NlPayload, Nlmsghdr}; use neli::socket::tokio::NlSocket; use neli::types::GenlBuffer; /// A generic netlink socket to send commands and receive messages #[cfg_attr(docsrs, doc(cfg(feature = "async")))] pub struct AsyncSocket { sock: NlSocket, family_id: u16, } impl TryFrom for AsyncSocket { type Error = std::io::Error; fn try_from(from: Socket) -> Result { Ok(Self { sock: NlSocket::new(from.sock)?, family_id: from.family_id, }) } } impl AsyncSocket { /// Create a new nl80211 socket with netlink pub fn connect() -> Result>> { Ok(Socket::connect()?.try_into()?) } async fn get_info_vec( &mut self, interface_index: Option, cmd: Nl80211Cmd, ) -> Result, NlError> where T: for<'a> TryFrom, Error = DeError>, { let msghdr = Genlmsghdr::::new(cmd, NL_80211_GENL_VERSION, { let mut attrs = GenlBuffer::new(); if let Some(interface_index) = interface_index { attrs.push( Nlattr::new(false, false, Nl80211Attr::AttrIfindex, interface_index).unwrap(), ); } attrs }); let nlhdr = { let len = None; let nl_type = self.family_id; let flags = NlmFFlags::new(&[NlmF::Request, NlmF::Dump]); let seq = None; let pid = None; let payload = NlPayload::Payload(msghdr); Nlmsghdr::new(len, nl_type, flags, seq, pid, payload) }; self.sock.send(&nlhdr).await?; let mut buf = Vec::new(); let mut retval = Vec::new(); loop { let res = self .sock .recv::>(&mut buf) .await?; for response in res { match response.nl_type { Nlmsg::Noop => (), Nlmsg::Error => panic!("Error"), Nlmsg::Done => return Ok(retval), _ => { retval.push( response .nl_payload .get_payload() .unwrap() .get_attr_handle() .try_into()?, ); } }; } } } /// Get information for all your wifi interfaces /// /// # Example /// /// ```no_run /// # use neli_wifi::AsyncSocket; /// # use std::error::Error; /// # async fn test() -> Result<(), Box>{ /// let wifi_interfaces = AsyncSocket::connect()?.get_interfaces_info().await?; /// for wifi_interface in wifi_interfaces { /// println!("{:#?}", wifi_interface); /// } /// # Ok(()) /// # }; ///``` pub async fn get_interfaces_info(&mut self) -> Result, NlError> { self.get_info_vec(None, Nl80211Cmd::CmdGetInterface).await } /// Get access point information for a specific interface /// /// # Example /// /// ```no_run /// # use neli_wifi::AsyncSocket; /// # use std::error::Error; /// # async fn test() -> Result<(), Box> { /// let mut socket = AsyncSocket::connect()?; /// // First of all we need to get wifi interface information to get more data /// let wifi_interfaces = socket.get_interfaces_info().await?; /// for wifi_interface in wifi_interfaces { /// if let Some(index) = wifi_interface.index { /// // Then for each wifi interface we can fetch station information /// for station_info in socket.get_station_info(index).await? { /// println!("{:#?}", station_info); /// } /// } /// } /// # Ok(()) /// # } ///``` pub async fn get_station_info( &mut self, interface_index: i32, ) -> Result, NlError> { self.get_info_vec(Some(interface_index), Nl80211Cmd::CmdGetStation) .await } pub async fn get_bss_info(&mut self, interface_index: i32) -> Result, NlError> { self.get_info_vec(Some(interface_index), Nl80211Cmd::CmdGetScan) .await } } impl From for NlSocket { /// Returns the underlying generic netlink socket fn from(sock: AsyncSocket) -> Self { sock.sock } } neli-wifi-0.6.1/src/attr.rs000064400000000000000000001103601046102023000136230ustar 00000000000000use neli::attr::AttrHandle; use neli::consts::genl::NlAttrType; use neli::genl::Nlattr; use neli::types::{Buffer, GenlBuffer}; use neli_proc_macros::neli_enum; pub type Attrs<'a, T> = AttrHandle<'a, GenlBuffer, Nlattr>; #[neli_enum(serialized_type = "u16")] pub enum NlaNested { Unspec = 0, } impl NlAttrType for NlaNested {} /// nl80211Attrs /// /// Enumeration from nl80211/nl80211.h:1929 #[neli_enum(serialized_type = "u16")] pub enum Nl80211Attr { AttrUnspec = 0, AttrWiphy = 1, AttrWiphyName = 2, AttrIfindex = 3, AttrIfname = 4, AttrIftype = 5, AttrMac = 6, AttrKeyData = 7, AttrKeyIdx = 8, AttrKeyCipher = 9, AttrKeySeq = 10, AttrKeyDefault = 11, AttrBeaconInterval = 12, AttrDtimPeriod = 13, AttrBeaconHead = 14, AttrBeaconTail = 15, AttrStaAid = 16, AttrStaFlags = 17, AttrStaListenInterval = 18, AttrStaSupportedRates = 19, AttrStaVlan = 20, AttrStaInfo = 21, AttrWiphyBands = 22, AttrMntrFlags = 23, AttrMeshId = 24, AttrStaPlinkAction = 25, AttrMpathNextHop = 26, AttrMpathInfo = 27, AttrBssCtsProt = 28, AttrBssShortPreamble = 29, AttrBssShortSlotTime = 30, AttrHtCapability = 31, AttrSupportedIftypes = 32, AttrRegAlpha2 = 33, AttrRegRules = 34, AttrMeshConfig = 35, AttrBssBasicRates = 36, AttrWiphyTxqParams = 37, AttrWiphyFreq = 38, AttrWiphyChannelType = 39, AttrKeyDefaultMgmt = 40, AttrMgmtSubtype = 41, AttrIe = 42, AttrMaxNumScanSsids = 43, AttrScanFrequencies = 44, AttrScanSsids = 45, AttrGeneration = 46, AttrBss = 47, AttrRegInitiator = 48, AttrRegType = 49, AttrSupportedCommands = 50, AttrFrame = 51, AttrSsid = 52, AttrAuthType = 53, AttrReasonCode = 54, AttrKeyType = 55, AttrMaxScanIeLen = 56, AttrCipherSuites = 57, AttrFreqBefore = 58, AttrFreqAfter = 59, AttrFreqFixed = 60, AttrWiphyRetryShort = 61, AttrWiphyRetryLong = 62, AttrWiphyFragThreshold = 63, AttrWiphyRtsThreshold = 64, AttrTimedOut = 65, AttrUseMfp = 66, AttrStaFlags2 = 67, AttrControlPort = 68, AttrTestdata = 69, AttrPrivacy = 70, AttrDisconnectedByAp = 71, AttrStatusCode = 72, AttrCipherSuitesPairwise = 73, AttrCipherSuiteGroup = 74, AttrWpaVersions = 75, AttrAkmSuites = 76, AttrReqIe = 77, AttrRespIe = 78, AttrPrevBssid = 79, AttrKey = 80, AttrKeys = 81, AttrPid = 82, Attr4addr = 83, AttrSurveyInfo = 84, AttrPmkid = 85, AttrMaxNumPmkids = 86, AttrDuration = 87, AttrCookie = 88, AttrWiphyCoverageClass = 89, AttrTxRates = 90, AttrFrameMatch = 91, AttrAck = 92, AttrPsState = 93, AttrCqm = 94, AttrLocalStateChange = 95, AttrApIsolate = 96, AttrWiphyTxPowerSetting = 97, AttrWiphyTxPowerLevel = 98, AttrTxFrameTypes = 99, AttrRxFrameTypes = 100, AttrFrameType = 101, AttrControlPortEthertype = 102, AttrControlPortNoEncrypt = 103, AttrSupportIbssRsn = 104, AttrWiphyAntennaTx = 105, AttrWiphyAntennaRx = 106, AttrMcastRate = 107, AttrOffchannelTxOk = 108, AttrBssHtOpmode = 109, AttrKeyDefaultTypes = 110, AttrMaxRemainOnChannelDuration = 111, AttrMeshSetup = 112, AttrWiphyAntennaAvailTx = 113, AttrWiphyAntennaAvailRx = 114, AttrSupportMeshAuth = 115, AttrStaPlinkState = 116, AttrWowlanTriggers = 117, AttrWowlanTriggersSupported = 118, AttrSchedScanInterval = 119, AttrInterfaceCombinations = 120, AttrSoftwareIftypes = 121, AttrRekeyData = 122, AttrMaxNumSchedScanSsids = 123, AttrMaxSchedScanIeLen = 124, AttrScanSuppRates = 125, AttrHiddenSsid = 126, AttrIeProbeResp = 127, AttrIeAssocResp = 128, AttrStaWme = 129, AttrSupportApUapsd = 130, AttrRoamSupport = 131, AttrSchedScanMatch = 132, AttrMaxMatchSets = 133, AttrPmksaCandidate = 134, AttrTxNoCckRate = 135, AttrTdlsAction = 136, AttrTdlsDialogToken = 137, AttrTdlsOperation = 138, AttrTdlsSupport = 139, AttrTdlsExternalSetup = 140, AttrDeviceApSme = 141, AttrDontWaitForAck = 142, AttrFeatureFlags = 143, AttrProbeRespOffload = 144, AttrProbeResp = 145, AttrDfsRegion = 146, AttrDisableHt = 147, AttrHtCapabilityMask = 148, AttrNoackMap = 149, AttrInactivityTimeout = 150, AttrRxSignalDbm = 151, AttrBgScanPeriod = 152, AttrWdev = 153, AttrUserRegHintType = 154, AttrConnFailedReason = 155, AttrSaeData = 156, AttrVhtCapability = 157, AttrScanFlags = 158, AttrChannelWidth = 159, AttrCenterFreq1 = 160, AttrCenterFreq2 = 161, AttrP2pCtwindow = 162, AttrP2pOppps = 163, AttrLocalMeshPowerMode = 164, AttrAclPolicy = 165, AttrMacAddrs = 166, AttrMacAclMax = 167, AttrRadarEvent = 168, AttrExtCapa = 169, AttrExtCapaMask = 170, AttrStaCapability = 171, AttrStaExtCapability = 172, AttrProtocolFeatures = 173, AttrSplitWiphyDump = 174, AttrDisableVht = 175, AttrVhtCapabilityMask = 176, AttrMdid = 177, AttrIeRic = 178, AttrCritProtId = 179, AttrMaxCritProtDuration = 180, AttrPeerAid = 181, AttrCoalesceRule = 182, AttrChSwitchCount = 183, AttrChSwitchBlockTx = 184, AttrCsaIes = 185, AttrCsaCOffBeacon = 186, AttrCsaCOffPresp = 187, AttrRxmgmtFlags = 188, AttrStaSupportedChannels = 189, AttrStaSupportedOperClasses = 190, AttrHandleDfs = 191, AttrSupport5Mhz = 192, AttrSupport10Mhz = 193, AttrOpmodeNotif = 194, AttrVendorId = 195, AttrVendorSubcmd = 196, AttrVendorData = 197, AttrVendorEvents = 198, AttrQosMap = 199, AttrMacHint = 200, AttrWiphyFreqHint = 201, AttrMaxApAssocSta = 202, AttrTdlsPeerCapability = 203, AttrSocketOwner = 204, AttrCsaCOffsetsTx = 205, AttrMaxCsaCounters = 206, AttrTdlsInitiator = 207, AttrUseRrm = 208, AttrWiphyDynAck = 209, AttrTsid = 210, AttrUserPrio = 211, AttrAdmittedTime = 212, AttrSmpsMode = 213, AttrOperClass = 214, AttrMacMask = 215, AttrWiphySelfManagedReg = 216, AttrExtFeatures = 217, AttrSurveyRadioStats = 218, AttrNetnsFd = 219, AttrSchedScanDelay = 220, AttrRegIndoor = 221, AttrMaxNumSchedScanPlans = 222, AttrMaxScanPlanInterval = 223, AttrMaxScanPlanIterations = 224, AttrSchedScanPlans = 225, AttrPbss = 226, AttrBssSelect = 227, AttrStaSupportP2pPs = 228, AttrPad = 229, AttrIftypeExtCapa = 230, AttrMuMimoGroupData = 231, AttrMuMimoFollowMacAddr = 232, AttrScanStartTimeTsf = 233, AttrScanStartTimeTsfBssid = 234, AttrMeasurementDuration = 235, AttrMeasurementDurationMandatory = 236, AttrMeshPeerAid = 237, AttrNanMasterPref = 238, AttrNanDual = 239, AttrNanFunc = 240, AttrNanMatch = 241, } impl NlAttrType for Nl80211Attr {} /// nl80211Iftype /// /// Enumeration from nl80211/nl80211.h:2384 #[neli_enum(serialized_type = "u16")] pub enum Nl80211Iftype { IftypeUnspecified = 0, IftypeAdhoc = 1, IftypeStation = 2, IftypeAp = 3, IftypeApVlan = 4, IftypeWds = 5, IftypeMonitor = 6, IftypeMeshPoint = 7, IftypeP2pClient = 8, IftypeP2pGo = 9, IftypeP2pDevice = 10, IftypeOcb = 11, IftypeNan = 12, } impl NlAttrType for Nl80211Iftype {} /// nl80211StaFlags as declared in nl80211/nl80211.h:2428 #[neli_enum(serialized_type = "u16")] pub enum Nl80211StaFlags { StaFlagInvalid = 0, StaFlagAuthorized = 1, StaFlagShortPreamble = 2, StaFlagWme = 3, StaFlagMfp = 4, StaFlagAuthenticated = 5, StaFlagTdlsPeer = 6, StaFlagAssociated = 7, } impl NlAttrType for Nl80211StaFlags {} /// nl80211StaP2pPsStatus /// /// Enumeration from nl80211/nl80211.h:2450 #[neli_enum(serialized_type = "u16")] pub enum Nl80211StaP2pPsStatus { P2pPsUnsupported = 0, P2pPsSupported = 1, } impl NlAttrType for Nl80211StaP2pPsStatus {} /// nl80211RateInfo /// /// Enumeration from nl80211/nl80211.h:2505 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RateInfo { RateInfoInvalid = 0, RateInfoBitrate = 1, RateInfoMcs = 2, RateInfo40MhzWidth = 3, RateInfoShortGi = 4, RateInfoBitrate32 = 5, RateInfoVhtMcs = 6, RateInfoVhtNss = 7, RateInfo80MhzWidth = 8, RateInfo80p80MhzWidth = 9, RateInfo160MhzWidth = 10, RateInfo10MhzWidth = 11, RateInfo5MhzWidth = 12, RateInfoHeMcs = 13, RateInfoHeNss = 14, RateInfoHeGi = 15, RateInfoHeDcm = 16, RateInfoHeRuAlloc = 17, RateInfo320MhzWidth = 18, RateInfoEhtMcs = 19, RateInfoEhtNss = 20, RateInfoEhtGi = 21, RateInfoEhtRuAlloc = 22, RateInfoS1gMcs = 23, RateInfoS1gNss = 24, RateInfo1MhzWidth = 25, RateInfo2MhzWidth = 26, RateInfo4MhzWidth = 27, RateInfo8MhzWidth = 28, RateInfo16MhzWidth = 29, } impl NlAttrType for Nl80211RateInfo {} /// nl80211StaBssParam /// /// Enumeration from nl80211/nl80211.h:2542 #[neli_enum(serialized_type = "u16")] pub enum Nl80211StaBssParam { StaBssParamInvalid = 0, StaBssParamCtsProt = 1, StaBssParamShortPreamble = 2, StaBssParamShortSlotTime = 3, StaBssParamDtimPeriod = 4, StaBssParamBeaconInterval = 5, } impl NlAttrType for Nl80211StaBssParam {} /// nl80211StaInfo /// /// Enumeration from nl80211/nl80211.h:2620 #[neli_enum(serialized_type = "u16")] pub enum Nl80211StaInfo { StaInfoInvalid = 0, StaInfoInactiveTime = 1, StaInfoRxBytes = 2, StaInfoTxBytes = 3, StaInfoLlid = 4, StaInfoPlid = 5, StaInfoPlinkState = 6, StaInfoSignal = 7, StaInfoTxBitrate = 8, StaInfoRxPackets = 9, StaInfoTxPackets = 10, StaInfoTxRetries = 11, StaInfoTxFailed = 12, StaInfoSignalAvg = 13, StaInfoRxBitrate = 14, StaInfoBssParam = 15, StaInfoConnectedTime = 16, StaInfoStaFlags = 17, StaInfoBeaconLoss = 18, StaInfoTOffset = 19, StaInfoLocalPm = 20, StaInfoPeerPm = 21, StaInfoNonpeerPm = 22, StaInfoRxBytes64 = 23, StaInfoTxBytes64 = 24, StaInfoChainSignal = 25, StaInfoChainSignalAvg = 26, StaInfoExpectedThroughput = 27, StaInfoRxDropMisc = 28, StaInfoBeaconRx = 29, StaInfoBeaconSignalAvg = 30, StaInfoTidStats = 31, StaInfoRxDuration = 32, StaInfoPad = 33, } impl NlAttrType for Nl80211StaInfo {} /// nl80211TidStats /// /// Enumeration from nl80211/nl80211.h:2675 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TidStats { TidStatsInvalid = 0, TidStatsRxMsdu = 1, TidStatsTxMsdu = 2, TidStatsTxMsduRetries = 3, TidStatsTxMsduFailed = 4, TidStatsPad = 5, } impl NlAttrType for Nl80211TidStats {} /// nl80211MpathFlags /// /// Enumeration from nl80211/nl80211.h:2697 #[neli_enum(serialized_type = "u16")] pub enum Nl80211MpathFlags { MpathFlagActive = 1 << 0, MpathFlagResolving = 1 << 1, MpathFlagSnValid = 1 << 2, MpathFlagFixed = 1 << 3, MpathFlagResolved = 1 << 4, } impl NlAttrType for Nl80211MpathFlags {} /// nl80211MpathFlags /// /// Enumeration from nl80211/nl80211.h:2697 #[neli_enum(serialized_type = "u16")] pub enum Nl80211MpathInfo { MpathInfoInvalid = 0, MpathInfoFrameQlen = 1, MpathInfoSn = 2, MpathInfoMetric = 3, MpathInfoExptime = 4, MpathInfoFlags = 5, MpathInfoDiscoveryTimeout = 6, MpathInfoDiscoveryRetries = 7, } impl NlAttrType for Nl80211MpathInfo {} /// nl80211BandAttr /// /// Enumeration from nl80211/nl80211.h:2757 #[neli_enum(serialized_type = "u16")] pub enum Nl80211BandAttr { BandAttrInvalid = 0, BandAttrFreqs = 1, BandAttrRates = 2, BandAttrHtMcsSet = 3, BandAttrHtCapa = 4, BandAttrHtAmpduFactor = 5, BandAttrHtAmpduDensity = 6, BandAttrVhtMcsSet = 7, BandAttrVhtCapa = 8, } impl NlAttrType for Nl80211BandAttr {} /// nl80211FrequencyAttr /// /// Enumeration from nl80211/nl80211.h:2833 #[neli_enum(serialized_type = "u16")] pub enum Nl80211FrequencyAttr { FrequencyAttrInvalid = 0, FrequencyAttrFreq = 1, FrequencyAttrDisabled = 2, FrequencyAttrNoIr = 3, FrequencyAttrNoIbss = 4, FrequencyAttrRadar = 5, FrequencyAttrMaxTxPower = 6, FrequencyAttrDfsState = 7, FrequencyAttrDfsTime = 8, FrequencyAttrNoHt40Minus = 9, FrequencyAttrNoHt40Plus = 10, FrequencyAttrNo80mhz = 11, FrequencyAttrNo160mhz = 12, FrequencyAttrDfsCacTime = 13, FrequencyAttrIndoorOnly = 14, FrequencyAttrIrConcurrent = 15, FrequencyAttrNo20mhz = 16, FrequencyAttrNo10mhz = 17, } impl NlAttrType for Nl80211FrequencyAttr {} /// nl80211BitrateAttr /// /// Enumeration from nl80211/nl80211.h:2873 #[neli_enum(serialized_type = "u16")] pub enum Nl80211BitrateAttr { BitrateAttrInvalid = 0, BitrateAttrRate = 1, BitrateAttr2ghzShortpreamble = 2, } impl NlAttrType for Nl80211BitrateAttr {} /// nl80211RegInitiator /// /// Enumeration from nl80211/nl80211.h:2899 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RegInitiator { RegdomSetByCore = 0, RegdomSetByUser = 1, RegdomSetByDriver = 2, RegdomSetByCountryIe = 3, } impl NlAttrType for Nl80211RegInitiator {} /// nl80211RegType /// /// Enumeration from nl80211/nl80211.h:2922 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RegType { RegdomTypeCountry = 0, RegdomTypeWorld = 1, RegdomTypeCustomWorld = 2, RegdomTypeIntersection = 3, } impl NlAttrType for Nl80211RegType {} /// nl80211RegRuleAttr /// /// Enumeration from nl80211/nl80211.h:2954 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RegRuleAttr { RegRuleAttrInvalid = 0, AttrRegRuleFlags = 1, AttrFreqRangeStart = 2, AttrFreqRangeEnd = 3, AttrFreqRangeMaxBw = 4, AttrPowerRuleMaxAntGain = 5, AttrPowerRuleMaxEirp = 6, AttrDfsCacTime = 7, } impl NlAttrType for Nl80211RegRuleAttr {} /// nl80211SchedScanMatchAttr /// /// Enumeration from nl80211/nl80211.h:2989 #[neli_enum(serialized_type = "u16")] pub enum Nl80211SchedScanMatchAttr { SchedScanMatchAttrInvalid = 0, SchedScanMatchAttrSsid = 1, SchedScanMatchAttrRssi = 2, } impl NlAttrType for Nl80211SchedScanMatchAttr {} /// nl80211RegRuleFlags /// /// Enumeration from nl80211/nl80211.h:3026 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RegRuleFlags { RrfNoOfdm = 1 << 0, RrfNoCck = 1 << 1, RrfNoIndoor = 1 << 2, RrfNoOutdoor = 1 << 3, RrfDfs = 1 << 4, RrfPtpOnly = 1 << 5, RrfPtmpOnly = 1 << 6, RrfNoIr = 1 << 7, RrfNoIbss = 1 << 8, RrfAutoBw = 1 << 11, RrfIrConcurrent = 1 << 12, RrfNoHt40minus = 1 << 13, RrfNoHt40plus = 1 << 14, RrfNo80mhz = 1 << 15, // RrfNo160mhz =1 << 16 } impl NlAttrType for Nl80211RegRuleFlags {} /// nl80211DfsRegions /// /// Enumeration from nl80211/nl80211.h:3061 #[neli_enum(serialized_type = "u16")] pub enum Nl80211DfsRegions { DfsUnset = 0, DfsFcc = 1, DfsEtsi = 2, DfsJp = 3, } impl NlAttrType for Nl80211DfsRegions {} /// nl80211UserRegHintType /// /// Enumeration from nl80211/nl80211.h:3085 #[neli_enum(serialized_type = "u16")] pub enum Nl80211UserRegHintType { UserRegHintUser = 0, UserRegHintCellBase = 1, UserRegHintIndoor = 2, } impl NlAttrType for Nl80211UserRegHintType {} /// nl80211SurveyInfo /// /// Enumeration from nl80211/nl80211.h:3118 #[neli_enum(serialized_type = "u16")] pub enum Nl80211SurveyInfo { SurveyInfoInvalid = 0, SurveyInfoFrequency = 1, SurveyInfoNoise = 2, SurveyInfoInUse = 3, SurveyInfoTime = 4, SurveyInfoTimeBusy = 5, SurveyInfoTimeExtBusy = 6, SurveyInfoTimeRx = 7, SurveyInfoTimeTx = 8, SurveyInfoTimeScan = 9, SurveyInfoPad = 10, } impl NlAttrType for Nl80211SurveyInfo {} /// nl80211MntrFlags /// /// Enumeration from nl80211/nl80211.h:3162 #[neli_enum(serialized_type = "u16")] pub enum Nl80211MntrFlags { MntrFlagInvalid = 0, MntrFlagFcsfail = 1, MntrFlagPlcpfail = 2, MntrFlagControl = 3, MntrFlagOtherBss = 4, MntrFlagCookFrames = 5, MntrFlagActive = 6, } impl NlAttrType for Nl80211MntrFlags {} /// nl80211MeshPowerMode /// /// Enumeration from nl80211/nl80211.h:3194 #[neli_enum(serialized_type = "u16")] pub enum Nl80211MeshPowerMode { MeshPowerUnknown = 0, MeshPowerActive = 1, MeshPowerLightSleep = 2, MeshPowerDeepSleep = 3, } impl NlAttrType for Nl80211MeshPowerMode {} /// nl80211MeshconfParams /// /// Enumeration from nl80211/nl80211.h:3312 #[neli_enum(serialized_type = "u16")] pub enum Nl80211MeshconfParams { MeshconfInvalid = 0, MeshconfRetryTimeout = 1, MeshconfConfirmTimeout = 2, MeshconfHoldingTimeout = 3, MeshconfMaxPeerLinks = 4, MeshconfMaxRetries = 5, MeshconfTtl = 6, MeshconfAutoOpenPlinks = 7, MeshconfHwmpMaxPreqRetries = 8, MeshconfPathRefreshTime = 9, MeshconfMinDiscoveryTimeout = 10, MeshconfHwmpActivePathTimeout = 11, MeshconfHwmpPreqMinInterval = 12, MeshconfHwmpNetDiamTrvsTime = 13, MeshconfHwmpRootmode = 14, MeshconfElementTtl = 15, MeshconfHwmpRannInterval = 16, MeshconfGateAnnouncements = 17, MeshconfHwmpPerrMinInterval = 18, MeshconfForwarding = 19, MeshconfRssiThreshold = 20, MeshconfSyncOffsetMaxNeighbor = 21, MeshconfHtOpmode = 22, MeshconfHwmpPathToRootTimeout = 23, MeshconfHwmpRootInterval = 24, MeshconfHwmpConfirmationInterval = 25, MeshconfPowerMode = 26, MeshconfAwakeWindow = 27, MeshconfPlinkTimeout = 28, } impl NlAttrType for Nl80211MeshconfParams {} /// nl80211MeshSetupParams /// /// Enumeration from nl80211/nl80211.h:3397 #[neli_enum(serialized_type = "u16")] pub enum Nl80211MeshSetupParams { MeshSetupInvalid = 0, MeshSetupEnableVendorPathSel = 1, MeshSetupEnableVendorMetric = 2, MeshSetupIe = 3, MeshSetupUserspaceAuth = 4, MeshSetupUserspaceAmpe = 5, MeshSetupEnableVendorSync = 6, MeshSetupUserspaceMpm = 7, MeshSetupAuthProtocol = 8, } impl NlAttrType for Nl80211MeshSetupParams {} /// nl80211TxqAttr /// /// Enumeration from nl80211/nl80211.h:3427 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TxqAttr { TxqAttrInvalid = 0, TxqAttrAc = 1, TxqAttrTxop = 2, TxqAttrCwmin = 3, TxqAttrCwmax = 4, TxqAttrAifs = 5, } impl NlAttrType for Nl80211TxqAttr {} /// nl80211Ac /// /// Enumeration from nl80211/nl80211.h:3440 #[neli_enum(serialized_type = "u16")] pub enum Nl80211Ac { AcVo = 0, AcVi = 1, AcBe = 2, AcBk = 3, } impl NlAttrType for Nl80211Ac {} /// nl80211ChannelType /// /// Enumeration from nl80211/nl80211.h:3464 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ChannelType { ChanNoHt = 0, ChanHt20 = 1, ChanHt40minus = 2, ChanHt40plus = 3, } impl NlAttrType for Nl80211ChannelType {} /// nl80211ChanWidth /// /// Enumeration from nl80211/nl80211.h:3490 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ChanWidth { ChanWidth20Noht = 0, ChanWidth20 = 1, ChanWidth40 = 2, ChanWidth80 = 3, ChanWidth80p80 = 4, ChanWidth160 = 5, ChanWidth5 = 6, ChanWidth10 = 7, } impl NlAttrType for Nl80211ChanWidth {} /// nl80211BssScanWidth /// /// Enumeration from nl80211/nl80211.h:3510 #[neli_enum(serialized_type = "u16")] pub enum Nl80211BssScanWidth { BssChanWidth20 = 0, BssChanWidth10 = 1, BssChanWidth5 = 2, } impl NlAttrType for Nl80211BssScanWidth {} /// nl80211Bss /// /// Enumeration from nl80211/nl80211.h:3565 #[neli_enum(serialized_type = "u16")] pub enum Nl80211Bss { BssInvalid = 0, BssBssid = 1, BssFrequency = 2, BssTsf = 3, BssBeaconInterval = 4, BssCapability = 5, BssInformationElements = 6, BssSignalMbm = 7, BssSignalUnspec = 8, BssStatus = 9, BssSeenMsAgo = 10, BssBeaconIes = 11, BssChanWidth = 12, BssBeaconTsf = 13, BssPrespData = 14, BssLastSeenBoottime = 15, BssPad = 16, BssParentTsf = 17, BssParentBssid = 18, } impl NlAttrType for Nl80211Bss {} /// nl80211BssStatus /// /// Enumeration from nl80211/nl80211.h:3603 #[neli_enum(serialized_type = "u16")] pub enum Nl80211BssStatus { BssStatusAuthenticated = 0, BssStatusAssociated = 1, BssStatusIbssJoined = 2, } impl NlAttrType for Nl80211BssStatus {} /// nl80211AuthType /// /// Enumeration from nl80211/nl80211.h:3623 #[neli_enum(serialized_type = "u16")] pub enum Nl80211AuthType { AuthtypeOpenSystem = 0, AuthtypeSharedKey = 1, AuthtypeFt = 2, AuthtypeNetworkEap = 3, AuthtypeSae = 4, AuthtypeNum = 5, AuthtypeMax = 4, AuthtypeAutomatic = 5, } impl NlAttrType for Nl80211AuthType {} /// nl80211KeyType /// /// Enumeration from nl80211/nl80211.h:3643 #[neli_enum(serialized_type = "u16")] pub enum Nl80211KeyType { KeytypeGroup = 0, KeytypePairwise = 1, KeytypePeerkey = 2, } impl NlAttrType for Nl80211KeyType {} /// nl80211Mfp /// /// Enumeration from nl80211/nl80211.h:3656 #[neli_enum(serialized_type = "u16")] pub enum Nl80211Mfp { MfpNo = 0, MfpRequired = 1, } impl NlAttrType for Nl80211Mfp {} /// nl80211WpaVersions /// /// Enumeration from nl80211/nl80211.h:3661 #[neli_enum(serialized_type = "u16")] pub enum Nl80211WpaVersions { WpaVersion1 = 1 << 0, WpaVersion2 = 1 << 1, } impl NlAttrType for Nl80211WpaVersions {} /// nl80211KeyDefaultTypes /// /// Enumeration from nl80211/nl80211.h:3675 #[neli_enum(serialized_type = "u16")] pub enum Nl80211KeyDefaultTypes { KeyDefaultTypeInvalid = 0, KeyDefaultTypeUnicast = 1, KeyDefaultTypeMulticast = 2, } impl NlAttrType for Nl80211KeyDefaultTypes {} /// nl80211KeyAttributes /// /// Enumeration from nl80211/nl80211.h:3705 #[neli_enum(serialized_type = "u16")] pub enum Nl80211KeyAttributes { KeyInvalid = 0, KeyData = 1, KeyIdx = 2, KeyCipher = 3, KeySeq = 4, KeyDefault = 5, KeyDefaultMgmt = 6, KeyType = 7, KeyDefaultTypes = 8, } impl NlAttrType for Nl80211KeyAttributes {} /// nl80211TxRateAttributes /// /// Enumeration from nl80211/nl80211.h:3736 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TxRateAttributes { TxrateInvalid = 0, TxrateLegacy = 1, TxrateHt = 2, TxrateVht = 3, TxrateGi = 4, } impl NlAttrType for Nl80211TxRateAttributes {} /// nl80211TxrateGi /// /// Enumeration from nl80211/nl80211.h:3759 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TxrateGi { TxrateDefaultGi = 0, TxrateForceSgi = 1, TxrateForceLgi = 2, } impl NlAttrType for Nl80211TxrateGi {} /// nl80211Band /// /// Enumeration from nl80211/nl80211.h:3773 #[neli_enum(serialized_type = "u16")] pub enum Nl80211Bandc { Band2ghz = 0, Band5ghz = 1, Band60ghz = 2, } impl NlAttrType for Nl80211Bandc {} /// nl80211PsState /// /// Enumeration from nl80211/nl80211.h:3786 #[neli_enum(serialized_type = "u16")] pub enum Nl80211PsState { PsDisabled = 0, PsEnabled = 1, } impl NlAttrType for Nl80211PsState {} /// nl80211AttrCqm /// /// Enumeration from nl80211/nl80211.h:3819 #[neli_enum(serialized_type = "u16")] pub enum Nl80211AttrCqm { AttrCqmInvalid = 0, AttrCqmRssiThold = 1, AttrCqmRssiHyst = 2, AttrCqmRssiThresholdEvent = 3, AttrCqmPktLossEvent = 4, AttrCqmTxeRate = 5, AttrCqmTxePkts = 6, AttrCqmTxeIntvl = 7, AttrCqmBeaconLossEvent = 8, } impl NlAttrType for Nl80211AttrCqm {} /// nl80211CqmRssiThresholdEvent /// /// Enumeration from nl80211/nl80211.h:3843 #[neli_enum(serialized_type = "u16")] pub enum Nl80211CqmRssiThresholdEvent { CqmRssiThresholdEventLow = 0, CqmRssiThresholdEventHigh = 1, CqmRssiBeaconLossEvent = 2, } impl NlAttrType for Nl80211CqmRssiThresholdEvent {} /// nl80211TxPowerSetting /// /// Enumeration from nl80211/nl80211.h:3856 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TxPowerSetting { TxPowerAutomatic = 0, TxPowerLimited = 1, TxPowerFixed = 2, } impl NlAttrType for Nl80211TxPowerSetting {} /// nl80211PacketPatternAttr /// /// Enumeration from nl80211/nl80211.h:3883 #[neli_enum(serialized_type = "u16")] pub enum Nl80211PacketPatternAttr { PktpatInvalid = 0, PktpatMask = 1, PktpatPattern = 2, PktpatOffset = 3, } impl NlAttrType for Nl80211PacketPatternAttr {} /// nl80211WowlanTriggers /// /// Enumeration from nl80211/nl80211.h:4011 #[neli_enum(serialized_type = "u16")] pub enum Nl80211WowlanTriggers { WowlanTrigInvalid = 0, WowlanTrigAny = 1, WowlanTrigDisconnect = 2, WowlanTrigMagicPkt = 3, WowlanTrigPktPattern = 4, WowlanTrigGtkRekeySupported = 5, WowlanTrigGtkRekeyFailure = 6, WowlanTrigEapIdentRequest = 7, WowlanTrig4wayHandshake = 8, WowlanTrigRfkillRelease = 9, WowlanTrigWakeupPkt80211 = 10, WowlanTrigWakeupPkt80211Len = 11, WowlanTrigWakeupPkt8023 = 12, WowlanTrigWakeupPkt8023Len = 13, WowlanTrigTcpConnection = 14, WowlanTrigWakeupTcpMatch = 15, WowlanTrigWakeupTcpConnlost = 16, WowlanTrigWakeupTcpNomoretokens = 17, WowlanTrigNetDetect = 18, WowlanTrigNetDetectResults = 19, } impl NlAttrType for Nl80211WowlanTriggers {} /// nl80211WowlanTcpAttrs /// /// Enumeration from nl80211/nl80211.h:4129 #[neli_enum(serialized_type = "u16")] pub enum Nl80211WowlanTcpAttrs { WowlanTcpInvalid = 0, WowlanTcpSrcIpv4 = 1, WowlanTcpDstIpv4 = 2, WowlanTcpDstMac = 3, WowlanTcpSrcPort = 4, WowlanTcpDstPort = 5, WowlanTcpDataPayload = 6, WowlanTcpDataPayloadSeq = 7, WowlanTcpDataPayloadToken = 8, WowlanTcpDataInterval = 9, WowlanTcpWakePayload = 10, WowlanTcpWakeMask = 11, } impl NlAttrType for Nl80211WowlanTcpAttrs {} /// nl80211AttrCoalesceRule /// /// Enumeration from nl80211/nl80211.h:4174 #[neli_enum(serialized_type = "u16")] pub enum Nl80211AttrCoalesceRule { CoalesceRuleInvalid = 0, AttrCoalesceRuleDelay = 1, AttrCoalesceRuleCondition = 2, AttrCoalesceRulePktPattern = 3, } impl NlAttrType for Nl80211AttrCoalesceRule {} /// nl80211CoalesceCondition /// /// Enumeration from nl80211/nl80211.h:4192 #[neli_enum(serialized_type = "u16")] pub enum Nl80211CoalesceCondition { CoalesceConditionMatch = 0, CoalesceConditionNoMatch = 1, } impl NlAttrType for Nl80211CoalesceCondition {} /// nl80211IfaceLimitAttrs /// /// Enumeration from nl80211/nl80211.h:4207 #[neli_enum(serialized_type = "u16")] pub enum Nl80211IfaceLimitAttrs { IfaceLimitUnspec = 0, IfaceLimitMax = 1, IfaceLimitTypes = 2, } impl NlAttrType for Nl80211IfaceLimitAttrs {} /// nl80211IfCombinationAttrs /// /// Enumeration from nl80211/nl80211.h:4263 #[neli_enum(serialized_type = "u16")] pub enum Nl80211IfCombinationAttrs { IfaceCombUnspec = 0, IfaceCombLimits = 1, IfaceCombMaxnum = 2, IfaceCombStaApBiMatch = 3, IfaceCombNumChannels = 4, IfaceCombRadarDetectWidths = 5, IfaceCombRadarDetectRegions = 6, } impl NlAttrType for Nl80211IfCombinationAttrs {} /// nl80211PlinkState /// /// Enumeration from nl80211/nl80211.h:4296 #[neli_enum(serialized_type = "u16")] pub enum Nl80211PlinkState { PlinkListen = 0, PlinkOpnSnt = 1, PlinkOpnRcvd = 2, PlinkCnfRcvd = 3, PlinkEstab = 4, PlinkHolding = 5, PlinkBlocked = 6, } impl NlAttrType for Nl80211PlinkState {} /// plinkActions /// /// Enumeration from nl80211/nl80211.h:4318 #[neli_enum(serialized_type = "u16")] pub enum PlinkActions { PlinkActionNoAction = 0, PlinkActionOpen = 1, PlinkActionBlock = 2, } impl NlAttrType for PlinkActions {} /// nl80211RekeyData /// /// Enumeration from nl80211/nl80211.h:4340 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RekeyData { RekeyDataInvalid = 0, RekeyDataKek = 1, RekeyDataKck = 2, RekeyDataReplayCtr = 3, } impl NlAttrType for Nl80211RekeyData {} /// nl80211HiddenSsid /// /// Enumeration from nl80211/nl80211.h:4360 #[neli_enum(serialized_type = "u16")] pub enum Nl80211HiddenSsid { HiddenSsidNotInUse = 0, HiddenSsidZeroLen = 1, HiddenSsidZeroContents = 2, } impl NlAttrType for Nl80211HiddenSsid {} /// nl80211StaWmeAttr /// /// Enumeration from nl80211/nl80211.h:4376 #[neli_enum(serialized_type = "u16")] pub enum Nl80211StaWmeAttr { StaWmeInvalid = 0, StaWmeUapsdQueues = 1, StaWmeMaxSp = 2, } impl NlAttrType for Nl80211StaWmeAttr {} /// nl80211PmksaCandidateAttr /// /// Enumeration from nl80211/nl80211.h:4398 #[neli_enum(serialized_type = "u16")] pub enum Nl80211PmksaCandidateAttr { PmksaCandidateInvalid = 0, PmksaCandidateIndex = 1, PmksaCandidateBssid = 2, PmksaCandidatePreauth = 3, } impl NlAttrType for Nl80211PmksaCandidateAttr {} /// nl80211TdlsOperation /// /// Enumeration from nl80211/nl80211.h:4417 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TdlsOperation { TdlsDiscoveryReq = 0, TdlsSetup = 1, TdlsTeardown = 2, TdlsEnableLink = 3, TdlsDisableLink = 4, } impl NlAttrType for Nl80211TdlsOperation {} /// nl80211FeatureFlags /// /// Enumeration from nl80211/nl80211.h:4526 #[neli_enum(serialized_type = "u16")] pub enum Nl80211FeatureFlags { FeatureSkTxStatus = 1 << 0, FeatureHtIbss = 1 << 1, FeatureInactivityTimer = 1 << 2, FeatureCellBaseRegHints = 1 << 3, FeatureP2pDeviceNeedsChannel = 1 << 4, FeatureSae = 1 << 5, FeatureLowPriorityScan = 1 << 6, FeatureScanFlush = 1 << 7, FeatureApScan = 1 << 8, FeatureVifTxpower = 1 << 9, FeatureNeedObssScan = 1 << 10, FeatureP2pGoCtwin = 1 << 11, FeatureP2pGoOppps = 1 << 12, FeatureAdvertiseChanLimits = 1 << 14, FeatureFullApClientState = 1 << 15, // FeatureUserspaceMpm =1 << 16, // FeatureActiveMonitor =1 << 17, // FeatureApModeChanWidthChange =1 << 18, // FeatureDsParamSetIeInProbes =1 << 19, // FeatureWfaTpcIeInProbes =1 << 20, // FeatureQuiet =1 << 21, // FeatureTxPowerInsertion =1 << 22, // FeatureAcktoEstimation =1 << 23, // FeatureStaticSmps =1 << 24, // FeatureDynamicSmps =1 << 25, // FeatureSupportsWmmAdmission =1 << 26, // FeatureMacOnCreate =1 << 27, // FeatureTdlsChannelSwitch =1 << 28, // FeatureScanRandomMacAddr =1 << 29, // FeatureSchedScanRandomMacAddr=1 << 30, // FeatureNdRandomMacAddr =1 << 31 } impl NlAttrType for Nl80211FeatureFlags {} /// nl80211ExtFeatureIndex /// /// Enumeration from nl80211/nl80211.h:4595 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ExtFeatureIndex { ExtFeatureVhtIbss = 0, ExtFeatureRrm = 1, ExtFeatureMuMimoAirSniffer = 2, ExtFeatureScanStartTime = 3, ExtFeatureBssParentTsf = 4, ExtFeatureSetScanDwell = 5, ExtFeatureBeaconRateLegacy = 6, ExtFeatureBeaconRateHt = 7, ExtFeatureBeaconRateVht = 8, } impl NlAttrType for Nl80211ExtFeatureIndex {} /// nl80211ProbeRespOffloadSupportAttr /// /// Enumeration from nl80211/nl80211.h:4625 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ProbeRespOffloadSupportAttr { ProbeRespOffloadSupportWps = 1 << 0, ProbeRespOffloadSupportWps2 = 1 << 1, ProbeRespOffloadSupportP2p = 1 << 2, ProbeRespOffloadSupport80211u = 1 << 3, } impl NlAttrType for Nl80211ProbeRespOffloadSupportAttr {} /// nl80211ConnectFailedReason /// /// Enumeration from nl80211/nl80211.h:4638 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ConnectFailedReason { ConnFailMaxClients = 0, ConnFailBlockedClient = 1, } impl NlAttrType for Nl80211ConnectFailedReason {} /// nl80211ScanFlags /// /// Enumeration from nl80211/nl80211.h:4667 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ScanFlags { ScanFlagLowPriority = 1 << 0, ScanFlagFlush = 1 << 1, ScanFlagAp = 1 << 2, ScanFlagRandomAddr = 1 << 3, } impl NlAttrType for Nl80211ScanFlags {} /// nl80211AclPolicy /// /// Enumeration from nl80211/nl80211.h:4687 #[neli_enum(serialized_type = "u16")] pub enum Nl80211AclPolicy { AclPolicyAcceptUnlessListed = 0, AclPolicyDenyUnlessListed = 1, } impl NlAttrType for Nl80211AclPolicy {} /// nl80211SmpsMode /// /// Enumeration from nl80211/nl80211.h:4702 #[neli_enum(serialized_type = "u16")] pub enum Nl80211SmpsMode { SmpsOff = 0, SmpsStatic = 1, SmpsDynamic = 2, } impl NlAttrType for Nl80211SmpsMode {} /// nl80211RadarEvent /// /// Enumeration from nl80211/nl80211.h:4726 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RadarEvent { RadarDetected = 0, RadarCacFinished = 1, RadarCacAborted = 2, RadarNopFinished = 3, } impl NlAttrType for Nl80211RadarEvent {} /// nl80211DfsState /// /// Enumeration from nl80211/nl80211.h:4744 #[neli_enum(serialized_type = "u16")] pub enum Nl80211DfsState { DfsUsable = 0, DfsUnavailable = 1, DfsAvailable = 2, } impl NlAttrType for Nl80211DfsState {} /// nl80211ProtocolFeatures /// /// Enumeration from nl80211/nl80211.h:4758 #[neli_enum(serialized_type = "u16")] pub enum Nl80211ProtocolFeatures { ProtocolFeatureSplitWiphyDump = 1 << 0, } impl NlAttrType for Nl80211ProtocolFeatures {} /// nl80211CritProtoId /// /// Enumeration from nl80211/nl80211.h:4771 #[neli_enum(serialized_type = "u16")] pub enum Nl80211CritProtoId { CritProtoUnspec = 0, CritProtoDhcp = 1, CritProtoEapol = 2, CritProtoApipa = 3, } impl NlAttrType for Nl80211CritProtoId {} /// nl80211RxmgmtFlags /// /// Enumeration from nl80211/nl80211.h:4790 #[neli_enum(serialized_type = "u16")] pub enum Nl80211RxmgmtFlags { RxmgmtFlagAnswered = 1 << 0, } impl NlAttrType for Nl80211RxmgmtFlags {} /// nl80211TdlsPeerCapability /// /// Enumeration from nl80211/nl80211.h:4824 #[neli_enum(serialized_type = "u16")] pub enum Nl80211TdlsPeerCapability { TdlsPeerHt = 1 << 0, TdlsPeerVht = 1 << 1, TdlsPeerWmm = 1 << 2, } impl NlAttrType for Nl80211TdlsPeerCapability {} /// nl80211SchedScanPlan /// /// Enumeration from nl80211/nl80211.h:4843 #[neli_enum(serialized_type = "u16")] pub enum Nl80211SchedScanPlan { SchedScanPlanInvalid = 0, SchedScanPlanInterval = 1, SchedScanPlanIterations = 2, } impl NlAttrType for Nl80211SchedScanPlan {} /// nl80211BssSelectAttr /// /// Enumeration from nl80211/nl80211.h:4887 #[neli_enum(serialized_type = "u16")] pub enum Nl80211BssSelectAttr { BssSelectAttrInvalid = 0, BssSelectAttrRssi = 1, BssSelectAttrBandPref = 2, BssSelectAttrRssiAdjust = 3, } impl NlAttrType for Nl80211BssSelectAttr {} /// nl80211NanDualBandConf /// /// Enumeration from nl80211/nl80211.h:4907 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanDualBandConf { NanBandDefault = 1 << 0, NanBand2ghz = 1 << 1, NanBand5ghz = 1 << 2, } impl NlAttrType for Nl80211NanDualBandConf {} /// nl80211NanFunctionType /// /// Enumeration from nl80211/nl80211.h:4922 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanFunctionType { NanFuncPublish = 0, NanFuncSubscribe = 1, NanFuncFollowUp = 2, NanFuncTypeAfterLast = 3, NanFuncMaxType = 2, } impl NlAttrType for Nl80211NanFunctionType {} /// nl80211NanPublishType /// /// Enumeration from nl80211/nl80211.h:4940 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanPublishType { NanSolicitedPublish = 1 << 0, NanUnsolicitedPublish = 1 << 1, } impl NlAttrType for Nl80211NanPublishType {} /// nl80211NanFuncTermReason /// /// Enumeration from nl80211/nl80211.h:4954 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanFuncTermReason { NanFuncTermReasonUserRequest = 0, NanFuncTermReasonTtlExpired = 1, NanFuncTermReasonError = 2, } impl NlAttrType for Nl80211NanFuncTermReason {} /// nl80211NanFuncAttributes /// /// Enumeration from nl80211/nl80211.h:5006 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanFuncAttributes { NanFuncInvalid = 0, NanFuncType = 1, NanFuncServiceId = 2, NanFuncPublishType = 3, NanFuncPublishBcast = 4, NanFuncSubscribeActive = 5, NanFuncFollowUpId = 6, NanFuncFollowUpReqId = 7, NanFuncFollowUpDest = 8, NanFuncCloseRange = 9, NanFuncTtl = 10, NanFuncServiceInfo = 11, NanFuncSrf = 12, NanFuncRxMatchFilter = 13, NanFuncTxMatchFilter = 14, NanFuncInstanceId = 15, NanFuncTermReason = 16, } impl NlAttrType for Nl80211NanFuncAttributes {} /// nl80211NanSrfAttributes /// /// Enumeration from nl80211/nl80211.h:5045 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanSrfAttributes { NanSrfInvalid = 0, NanSrfInclude = 1, NanSrfBf = 2, NanSrfBfIdx = 3, NanSrfMacAddrs = 4, } impl NlAttrType for Nl80211NanSrfAttributes {} /// nl80211NanMatchAttributes /// /// Enumeration from nl80211/nl80211.h:5070 #[neli_enum(serialized_type = "u16")] pub enum Nl80211NanMatchAttributes { NanMatchInvalid = 0, NanMatchFuncLocal = 1, NanMatchFuncPeer = 2, } impl NlAttrType for Nl80211NanMatchAttributes {} neli-wifi-0.6.1/src/bss.rs000064400000000000000000000217621046102023000134470ustar 00000000000000use std::fmt; use crate::attr::{Attrs, Nl80211Attr, Nl80211Bss}; use neli::attr::Attribute; use neli::err::DeError; /// A struct representing a BSS (Basic Service Set) #[non_exhaustive] #[derive(Default, Clone, PartialEq, Eq)] pub struct Bss { /// BSSID pub bssid: Option>, /// Frequency in MHz pub frequency: Option, /// Beacon interval of the (I)BSS pub beacon_interval: Option, /// Age of this BSS entry in ms pub seen_ms_ago: Option, /// Status, if this BSS is "used" pub status: Option, /// Signal strength of probe response/beacon in mBm (100 * dBm) pub signal: Option, /// binary attribute containing the raw information elements from the probe response/beacon. pub information_elements: Option>, } impl TryFrom> for Bss { type Error = DeError; fn try_from(attrs: Attrs<'_, Nl80211Attr>) -> Result { let mut res = Self::default(); if let Some(bss) = attrs.get_attribute(Nl80211Attr::AttrBss) { let attrs = bss.get_attr_handle::()?; for attr in attrs.iter() { match attr.nla_type.nla_type { Nl80211Bss::BssBssid => { res.bssid = Some(attr.get_payload_as_with_len()?); } Nl80211Bss::BssFrequency => { res.frequency = Some(attr.get_payload_as()?); } Nl80211Bss::BssBeaconInterval => { res.beacon_interval = Some(attr.get_payload_as()?); } Nl80211Bss::BssSeenMsAgo => { res.seen_ms_ago = Some(attr.get_payload_as()?); } Nl80211Bss::BssStatus => { res.status = Some(attr.get_payload_as()?); } Nl80211Bss::BssSignalMbm => { res.signal = Some(attr.get_payload_as()?); } Nl80211Bss::BssInformationElements => { res.information_elements = Some(attr.get_payload_as_with_len()?); } _ => (), } } } Ok(res) } } impl fmt::Debug for Bss { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Bss") .field("bssid", &self.bssid) .field("frequency", &self.frequency) .field("beacon_interval", &self.beacon_interval) .field("seen_ms_ago", &self.seen_ms_ago) .field("status", &self.status) .field("signal", &self.signal) .field("information_elements", &"...") .finish_non_exhaustive() } } #[cfg(test)] mod test_bss { use super::*; use crate::attr::Nl80211Attr::*; use neli::attr::AttrHandle; use neli::genl::{AttrType, Nlattr}; use neli::types::Buffer; fn new_attr(t: Nl80211Attr, d: Vec) -> Nlattr { Nlattr { nla_len: (4 + d.len()) as _, nla_type: AttrType { nla_nested: false, nla_network_order: true, nla_type: t, }, nla_payload: d.into(), } } #[test] fn test_parse() { let handler = vec![ new_attr(AttrGeneration, vec![28, 4, 0, 0]), new_attr(AttrIfindex, vec![3, 0, 0, 0]), new_attr(AttrWdev, vec![1, 0, 0, 0, 0, 0, 0, 0]), new_attr( AttrBss, vec![ 10, 0, 1, 0, 255, 255, 255, 255, 255, 255, 0, 0, 4, 0, 14, 0, 12, 0, 3, 0, 132, 12, 93, 163, 39, 0, 0, 0, 95, 1, 6, 0, 0, 8, 83, 70, 82, 45, 49, 99, 50, 56, 1, 8, 130, 132, 139, 150, 36, 48, 72, 108, 3, 1, 1, 7, 6, 68, 69, 32, 1, 13, 20, 32, 1, 0, 35, 2, 16, 0, 42, 1, 0, 50, 4, 12, 18, 24, 96, 48, 24, 1, 0, 0, 15, 172, 2, 2, 0, 0, 15, 172, 4, 0, 15, 172, 2, 1, 0, 0, 15, 172, 2, 12, 0, 11, 5, 1, 0, 80, 0, 0, 70, 5, 114, 8, 1, 0, 0, 45, 26, 188, 9, 27, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 22, 1, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 8, 4, 0, 8, 0, 0, 0, 0, 64, 221, 131, 0, 80, 242, 4, 16, 74, 0, 1, 16, 16, 68, 0, 1, 2, 16, 59, 0, 1, 3, 16, 71, 0, 16, 65, 133, 194, 155, 156, 12, 135, 126, 154, 135, 125, 82, 84, 30, 42, 138, 16, 33, 0, 8, 83, 97, 103, 101, 109, 99, 111, 109, 16, 35, 0, 8, 83, 97, 103, 101, 109, 99, 111, 109, 16, 36, 0, 6, 49, 50, 51, 52, 53, 54, 16, 66, 0, 7, 48, 48, 48, 48, 48, 48, 49, 16, 84, 0, 8, 0, 6, 0, 80, 242, 4, 0, 1, 16, 17, 0, 10, 83, 97, 103, 101, 109, 99, 111, 109, 65, 80, 16, 8, 0, 2, 32, 8, 16, 60, 0, 1, 3, 16, 73, 0, 6, 0, 55, 42, 0, 1, 32, 221, 9, 0, 16, 24, 2, 1, 0, 12, 0, 0, 221, 26, 0, 80, 242, 1, 1, 0, 0, 80, 242, 2, 2, 0, 0, 80, 242, 4, 0, 80, 242, 2, 1, 0, 0, 80, 242, 2, 221, 24, 0, 80, 242, 2, 1, 1, 132, 0, 3, 164, 0, 0, 39, 164, 0, 0, 66, 67, 94, 0, 98, 50, 47, 0, 0, 12, 0, 13, 0, 187, 118, 116, 163, 39, 0, 0, 0, 19, 1, 11, 0, 0, 8, 83, 70, 82, 45, 49, 99, 50, 56, 1, 8, 130, 132, 139, 150, 36, 48, 72, 108, 3, 1, 1, 5, 4, 0, 1, 0, 0, 7, 6, 68, 69, 32, 1, 13, 20, 32, 1, 0, 35, 2, 16, 0, 42, 1, 0, 50, 4, 12, 18, 24, 96, 48, 24, 1, 0, 0, 15, 172, 2, 2, 0, 0, 15, 172, 4, 0, 15, 172, 2, 1, 0, 0, 15, 172, 2, 12, 0, 11, 5, 1, 0, 80, 0, 0, 70, 5, 114, 8, 1, 0, 0, 45, 26, 188, 9, 27, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 22, 1, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 8, 4, 0, 8, 0, 0, 0, 0, 64, 221, 49, 0, 80, 242, 4, 16, 74, 0, 1, 16, 16, 68, 0, 1, 2, 16, 71, 0, 16, 65, 133, 194, 155, 156, 12, 135, 126, 154, 135, 125, 82, 84, 30, 42, 138, 16, 60, 0, 1, 3, 16, 73, 0, 6, 0, 55, 42, 0, 1, 32, 221, 9, 0, 16, 24, 2, 1, 0, 12, 0, 0, 221, 26, 0, 80, 242, 1, 1, 0, 0, 80, 242, 2, 2, 0, 0, 80, 242, 4, 0, 80, 242, 2, 1, 0, 0, 80, 242, 2, 221, 24, 0, 80, 242, 2, 1, 1, 132, 0, 3, 164, 0, 0, 39, 164, 0, 0, 66, 67, 94, 0, 98, 50, 47, 0, 0, 6, 0, 4, 0, 100, 0, 0, 0, 6, 0, 5, 0, 17, 21, 0, 0, 8, 0, 2, 0, 108, 9, 0, 0, 8, 0, 12, 0, 0, 0, 0, 0, 8, 0, 10, 0, 100, 0, 0, 0, 8, 0, 7, 0, 76, 235, 255, 255, 8, 0, 9, 0, 1, 0, 0, 0, ], ), ]; let bss: Bss = AttrHandle::new(handler.into_iter().collect()) .try_into() .unwrap(); let expected_bss = Bss { bssid: Some(vec![255, 255, 255, 255, 255, 255]), frequency: Some(u32::from_le_bytes([108, 9, 0, 0])), beacon_interval: Some(u16::from_le_bytes([100, 0])), seen_ms_ago: Some(u32::from_le_bytes([100, 0, 0, 0])), status: Some(u32::from_le_bytes([1, 0, 0, 0])), signal: Some(i32::from_le_bytes([76, 235, 255, 255])), information_elements: Some(vec![ 0, 8, 83, 70, 82, 45, 49, 99, 50, 56, 1, 8, 130, 132, 139, 150, 36, 48, 72, 108, 3, 1, 1, 7, 6, 68, 69, 32, 1, 13, 20, 32, 1, 0, 35, 2, 16, 0, 42, 1, 0, 50, 4, 12, 18, 24, 96, 48, 24, 1, 0, 0, 15, 172, 2, 2, 0, 0, 15, 172, 4, 0, 15, 172, 2, 1, 0, 0, 15, 172, 2, 12, 0, 11, 5, 1, 0, 80, 0, 0, 70, 5, 114, 8, 1, 0, 0, 45, 26, 188, 9, 27, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 22, 1, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 8, 4, 0, 8, 0, 0, 0, 0, 64, 221, 131, 0, 80, 242, 4, 16, 74, 0, 1, 16, 16, 68, 0, 1, 2, 16, 59, 0, 1, 3, 16, 71, 0, 16, 65, 133, 194, 155, 156, 12, 135, 126, 154, 135, 125, 82, 84, 30, 42, 138, 16, 33, 0, 8, 83, 97, 103, 101, 109, 99, 111, 109, 16, 35, 0, 8, 83, 97, 103, 101, 109, 99, 111, 109, 16, 36, 0, 6, 49, 50, 51, 52, 53, 54, 16, 66, 0, 7, 48, 48, 48, 48, 48, 48, 49, 16, 84, 0, 8, 0, 6, 0, 80, 242, 4, 0, 1, 16, 17, 0, 10, 83, 97, 103, 101, 109, 99, 111, 109, 65, 80, 16, 8, 0, 2, 32, 8, 16, 60, 0, 1, 3, 16, 73, 0, 6, 0, 55, 42, 0, 1, 32, 221, 9, 0, 16, 24, 2, 1, 0, 12, 0, 0, 221, 26, 0, 80, 242, 1, 1, 0, 0, 80, 242, 2, 2, 0, 0, 80, 242, 4, 0, 80, 242, 2, 1, 0, 0, 80, 242, 2, 221, 24, 0, 80, 242, 2, 1, 1, 132, 0, 3, 164, 0, 0, 39, 164, 0, 0, 66, 67, 94, 0, 98, 50, 47, 0, ]), }; assert_eq!(bss, expected_bss) } } neli-wifi-0.6.1/src/cmd.rs000064400000000000000000000070331046102023000134160ustar 00000000000000use neli::consts::genl::Cmd; use neli_proc_macros::neli_enum; /// nl80211Commands /// /// /// /// Enumeration from nl80211/nl80211.h:880 #[neli_enum(serialized_type = "u8")] pub enum Nl80211Cmd { CmdUnspec = 0, CmdGetWiphy = 1, CmdSetWiphy = 2, CmdNewWiphy = 3, CmdDelWiphy = 4, CmdGetInterface = 5, CmdSetInterface = 6, CmdNewInterface = 7, CmdDelInterface = 8, CmdGetKey = 9, CmdSetKey = 10, CmdNewKey = 11, CmdDelKey = 12, CmdGetBeacon = 13, CmdSetBeacon = 14, CmdStartAp = 15, CmdNewBeacon = 15, //CmdStartAp, CmdStopAp = 16, CmdDelBeacon = 16, //CmdStopAp, CmdGetStation = 17, CmdSetStation = 18, CmdNewStation = 19, CmdDelStation = 20, CmdGetMpath = 21, CmdSetMpath = 22, CmdNewMpath = 23, CmdDelMpath = 24, CmdSetBss = 25, CmdSetReg = 26, CmdReqSetReg = 27, CmdGetMeshConfig = 28, CmdSetMeshConfig = 29, CmdSetMgmtExtraIe = 30, CmdGetReg = 31, CmdGetScan = 32, CmdTriggerScan = 33, CmdNewScanResults = 34, CmdScanAborted = 35, CmdRegChange = 36, CmdAuthenticate = 37, CmdAssociate = 38, CmdDeauthenticate = 39, CmdDisassociate = 40, CmdMichaelMicFailure = 41, CmdRegBeaconHint = 42, CmdJoinIbss = 43, CmdLeaveIbss = 44, CmdTestmode = 45, CmdConnect = 46, CmdRoam = 47, CmdDisconnect = 48, CmdSetWiphyNetns = 49, CmdGetSurvey = 50, CmdNewSurveyResults = 51, CmdSetPmksa = 52, CmdDelPmksa = 53, CmdFlushPmksa = 54, CmdRemainOnChannel = 55, CmdCancelRemainOnChannel = 56, CmdSetTxBitrateMask = 57, CmdRegisterFrame = 58, CmdRegisterAction = 58, //CmdRegisterFrame, CmdFrame = 59, CmdAction = 59, //CmdFrame, CmdFrameTxStatus = 60, CmdActionTxStatus = 60, //CmdFrameTxStatus, CmdSetPowerSave = 61, CmdGetPowerSave = 62, CmdSetCqm = 63, CmdNotifyCqm = 64, CmdSetChannel = 65, CmdSetWdsPeer = 66, CmdFrameWaitCancel = 67, CmdJoinMesh = 68, CmdLeaveMesh = 69, CmdUnprotDeauthenticate = 70, CmdUnprotDisassociate = 71, CmdNewPeerCandidate = 72, CmdGetWowlan = 73, CmdSetWowlan = 74, CmdStartSchedScan = 75, CmdStopSchedScan = 76, CmdSchedScanResults = 77, CmdSchedScanStopped = 78, CmdSetRekeyOffload = 79, CmdPmksaCandidate = 80, CmdTdlsOper = 81, CmdTdlsMgmt = 82, CmdUnexpectedFrame = 83, CmdProbeClient = 84, CmdRegisterBeacons = 85, CmdUnexpected4addrFrame = 86, CmdSetNoackMap = 87, CmdChSwitchNotify = 88, CmdStartP2pDevice = 89, CmdStopP2pDevice = 90, CmdConnFailed = 91, CmdSetMcastRate = 92, CmdSetMacAcl = 93, CmdRadarDetect = 94, CmdGetProtocolFeatures = 95, CmdUpdateFtIes = 96, CmdFtEvent = 97, CmdCritProtocolStart = 98, CmdCritProtocolStop = 99, CmdGetCoalesce = 100, CmdSetCoalesce = 101, CmdChannelSwitch = 102, CmdVendor = 103, CmdSetQosMap = 104, CmdAddTxTs = 105, CmdDelTxTs = 106, CmdGetMpp = 107, CmdJoinOcb = 108, CmdLeaveOcb = 109, CmdChSwitchStartedNotify = 110, CmdTdlsChannelSwitch = 111, CmdTdlsCancelChannelSwitch = 112, CmdWiphyRegChange = 113, CmdAbortScan = 114, CmdStartNan = 115, CmdStopNan = 116, CmdAddNanFunction = 117, CmdDelNanFunction = 118, CmdChangeNanConfig = 119, CmdNanMatch = 120, CmdAfterLast = 121, CmdMax = 120, } impl Cmd for Nl80211Cmd {} neli-wifi-0.6.1/src/interface.rs000064400000000000000000000104561046102023000146160ustar 00000000000000use crate::attr::{Attrs, Nl80211Attr}; use neli::attr::Attribute; use neli::err::DeError; /// A struct representing a wifi interface #[non_exhaustive] #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct Interface { /// A netlink interface index. This index is used to fetch extra information with nl80211 pub index: Option, /// Interface essid pub ssid: Option>, /// Interface MAC address pub mac: Option>, /// Interface name (u8, String) pub name: Option>, /// Interface frequency of the selected channel (MHz) pub frequency: Option, /// Interface chanel pub channel: Option, /// Interface transmit power level in signed mBm units. pub power: Option, /// index of wiphy to operate on, cf. /sys/class/ieee80211//index pub phy: Option, /// Wireless device identifier, used for pseudo-devices that don't have a netdev pub device: Option, } impl TryFrom> for Interface { type Error = DeError; fn try_from(attrs: Attrs<'_, Nl80211Attr>) -> Result { let mut res = Self::default(); for attr in attrs.iter() { match attr.nla_type.nla_type { Nl80211Attr::AttrIfindex => { res.index = Some(attr.get_payload_as()?); } Nl80211Attr::AttrSsid => { res.ssid = Some(attr.get_payload_as_with_len()?); } Nl80211Attr::AttrMac => { res.mac = Some(attr.get_payload_as_with_len()?); } Nl80211Attr::AttrIfname => { res.name = Some(attr.get_payload_as_with_len()?); } Nl80211Attr::AttrWiphyFreq => { res.frequency = Some(attr.get_payload_as()?); } Nl80211Attr::AttrChannelWidth => { res.channel = Some(attr.get_payload_as()?); } Nl80211Attr::AttrWiphyTxPowerLevel => { res.power = Some(attr.get_payload_as()?); } Nl80211Attr::AttrWiphy => res.phy = Some(attr.get_payload_as()?), Nl80211Attr::AttrWdev => res.device = Some(attr.get_payload_as()?), _ => (), } } Ok(res) } } #[cfg(test)] mod test_interface { use super::*; use crate::attr::Nl80211Attr::*; use neli::attr::AttrHandle; use neli::genl::{AttrType, Nlattr}; use neli::types::Buffer; fn new_attr(t: Nl80211Attr, d: Vec) -> Nlattr { Nlattr { nla_len: (4 + d.len()) as _, nla_type: AttrType { nla_nested: false, nla_network_order: true, nla_type: t, }, nla_payload: d.into(), } } #[test] fn test_parser() { let handler = vec![ new_attr(AttrIfindex, vec![3, 0, 0, 0]), new_attr(AttrIfname, vec![119, 108, 112, 53, 115, 48]), new_attr(AttrWiphy, vec![0, 0, 0, 0]), new_attr(AttrIftype, vec![2, 0, 0, 0]), new_attr(AttrWdev, vec![1, 0, 0, 0, 0, 0, 0, 0]), new_attr(AttrMac, vec![255, 255, 255, 255, 255, 255]), new_attr(AttrWiphyFreq, vec![108, 9, 0, 0]), new_attr(AttrChannelWidth, vec![1, 0, 0, 0]), new_attr(AttrWiphyTxPowerLevel, vec![164, 6, 0, 0]), new_attr(AttrSsid, vec![101, 100, 117, 114, 111, 97, 109]), ]; let interface: Interface = AttrHandle::new(handler.into_iter().collect()) .try_into() .unwrap(); let expected_interface = Interface { index: Some(3), ssid: Some(vec![101, 100, 117, 114, 111, 97, 109]), mac: Some(vec![255, 255, 255, 255, 255, 255]), name: Some(vec![119, 108, 112, 53, 115, 48]), frequency: Some(u32::from_le_bytes([108, 9, 0, 0])), channel: Some(u32::from_le_bytes([1, 0, 0, 0])), power: Some(u32::from_le_bytes([164, 6, 0, 0])), phy: Some(u32::from_le_bytes([0, 0, 0, 0])), device: Some(u64::from_le_bytes([1, 0, 0, 0, 0, 0, 0, 0])), }; assert_eq!(interface, expected_interface) } } neli-wifi-0.6.1/src/lib.rs000064400000000000000000000006311046102023000134160ustar 00000000000000#![cfg_attr(docsrs, feature(doc_cfg))] pub const NL_80211_GENL_NAME: &str = "nl80211"; pub const NL_80211_GENL_VERSION: u8 = 1; mod cmd; pub use cmd::*; mod attr; pub use attr::*; mod bss; pub use bss::*; mod station; pub use station::*; mod interface; pub use interface::*; mod socket; pub use socket::*; #[cfg(feature = "async")] mod async_socket; #[cfg(feature = "async")] pub use async_socket::*; neli-wifi-0.6.1/src/socket.rs000064400000000000000000000110011046102023000141310ustar 00000000000000use crate::attr::Nl80211Attr; use crate::bss::Bss; use crate::cmd::Nl80211Cmd; use crate::interface::Interface; use crate::station::Station; use crate::{Attrs, NL_80211_GENL_NAME, NL_80211_GENL_VERSION}; use neli::consts::genl::{CtrlAttr, CtrlCmd}; use neli::consts::{nl::GenlId, nl::NlmF, nl::NlmFFlags, nl::Nlmsg, socket::NlFamily}; use neli::err::{DeError, NlError}; use neli::genl::{Genlmsghdr, Nlattr}; use neli::nl::{NlPayload, Nlmsghdr}; use neli::socket::NlSocketHandle; use neli::types::GenlBuffer; /// A generic netlink socket to send commands and receive messages pub struct Socket { pub(crate) sock: NlSocketHandle, pub(crate) family_id: u16, } impl Socket { /// Create a new nl80211 socket with netlink pub fn connect() -> Result>> { let mut sock = NlSocketHandle::connect(NlFamily::Generic, None, &[])?; let family_id = sock.resolve_genl_family(NL_80211_GENL_NAME)?; Ok(Self { sock, family_id }) } fn get_info_vec( &mut self, interface_index: Option, cmd: Nl80211Cmd, ) -> Result, NlError> where T: for<'a> TryFrom, Error = DeError>, { let msghdr = Genlmsghdr::::new(cmd, NL_80211_GENL_VERSION, { let mut attrs = GenlBuffer::new(); if let Some(interface_index) = interface_index { attrs.push( Nlattr::new(false, false, Nl80211Attr::AttrIfindex, interface_index).unwrap(), ); } attrs }); let nlhdr = { let len = None; let nl_type = self.family_id; let flags = NlmFFlags::new(&[NlmF::Request, NlmF::Dump]); let seq = None; let pid = None; let payload = NlPayload::Payload(msghdr); Nlmsghdr::new(len, nl_type, flags, seq, pid, payload) }; self.sock.send(nlhdr)?; let iter = self .sock .iter::>(false); let mut retval = Vec::new(); for response in iter { let response = response.unwrap(); match response.nl_type { Nlmsg::Noop => (), Nlmsg::Error => panic!("Error"), Nlmsg::Done => break, _ => retval.push( response .nl_payload .get_payload() .unwrap() .get_attr_handle() .try_into()?, ), } } Ok(retval) } /// Get information for all your wifi interfaces /// /// # Example /// /// ```no_run /// # use neli_wifi::Socket; /// # use std::error::Error; /// # fn main() -> Result<(), Box>{ /// let wifi_interfaces = Socket::connect()?.get_interfaces_info()?; /// for wifi_interface in wifi_interfaces { /// println!("{:#?}", wifi_interface); /// } /// # Ok(()) /// # } ///``` pub fn get_interfaces_info(&mut self) -> Result, NlError> { self.get_info_vec(None, Nl80211Cmd::CmdGetInterface) } /// Get access point information for a specific interface /// /// # Example /// /// ```no_run /// # use neli_wifi::Socket; /// # use std::error::Error; /// # fn main() -> Result<(), Box>{ /// // First of all we need to get wifi interface information to get more data /// let wifi_interfaces = Socket::connect()?.get_interfaces_info()?; /// for wifi_interface in wifi_interfaces { /// if let Some(index) = wifi_interface.index { /// // Then for each wifi interface we can fetch station information /// for station_info in Socket::connect()?.get_station_info(index)? { /// println!("{:#?}", station_info); /// } /// } /// } /// # Ok(()) /// # } ///``` pub fn get_station_info(&mut self, interface_index: i32) -> Result, NlError> { self.get_info_vec(Some(interface_index), Nl80211Cmd::CmdGetStation) } pub fn get_bss_info(&mut self, interface_index: i32) -> Result, NlError> { self.get_info_vec(Some(interface_index), Nl80211Cmd::CmdGetScan) } } impl From for NlSocketHandle { /// Returns the underlying generic netlink socket fn from(sock: Socket) -> Self { sock.sock } } neli-wifi-0.6.1/src/station.rs000064400000000000000000000400731046102023000143350ustar 00000000000000use crate::attr::{Attrs, Nl80211Attr, Nl80211RateInfo, Nl80211StaInfo}; use neli::attr::Attribute; use neli::err::DeError; /// A struct representing a remote station (Access Point) #[non_exhaustive] #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct Station { /// Signal strength average (dBm) pub average_signal: Option, /// Count of times beacon loss was detected pub beacon_loss: Option, /// Station bssid (u8) pub bssid: Option>, /// Time since the station is last connected in seconds pub connected_time: Option, /// Reception bitrate pub rx_bitrate: Option, /// Total received packets (MSDUs and MMPDUs) from this station pub rx_packets: Option, /// Signal strength of last received PPDU (dBm) pub signal: Option, /// Transmission bitrate pub tx_bitrate: Option, /// Total failed packets (MPDUs) to this station pub tx_failed: Option, /// Total transmitted packets (MSDUs and MMPDUs) to this station pub tx_packets: Option, /// Total retries (MPDUs) to this station pub tx_retries: Option, /// High Throughput Modulation and Coding Scheme (HT-MCS) (802.11n) pub ht_mcs: Option, /// Very High Throughput Modulation and Coding Scheme (VHT-MCS) (802.11ac) pub vht_mcs: Option, /// High Efficiency Modulation and Coding Scheme. (HE-MCS) (802.11ax) pub he_mcs: Option, /// Extremely High Throughput-Modulation and Coding Scheme (EHT-MCS) (802.11be) pub eht_mcs: Option, } impl TryFrom> for Station { type Error = DeError; fn try_from(attrs: Attrs<'_, Nl80211Attr>) -> Result { let mut res = Self::default(); if let Some(bssid) = attrs.get_attribute(Nl80211Attr::AttrMac) { res.bssid = Some(Vec::from(bssid.nla_payload.as_ref())); } if let Some(info) = attrs.get_attribute(Nl80211Attr::AttrStaInfo) { let attrs = info.get_attr_handle::().unwrap(); for attr in attrs.iter() { match attr.nla_type.nla_type { Nl80211StaInfo::StaInfoSignal => res.signal = Some(attr.get_payload_as()?), Nl80211StaInfo::StaInfoSignalAvg => { res.average_signal = Some(attr.get_payload_as()?) } Nl80211StaInfo::StaInfoBeaconLoss => { res.beacon_loss = Some(attr.get_payload_as()?) } Nl80211StaInfo::StaInfoConnectedTime => { res.connected_time = Some(attr.get_payload_as()?) } Nl80211StaInfo::StaInfoRxPackets => { res.rx_packets = Some(attr.get_payload_as()?) } Nl80211StaInfo::StaInfoTxPackets => { res.tx_packets = Some(attr.get_payload_as()?) } Nl80211StaInfo::StaInfoTxRetries => { res.tx_retries = Some(attr.get_payload_as()?) } Nl80211StaInfo::StaInfoTxFailed => res.tx_failed = Some(attr.get_payload_as()?), Nl80211StaInfo::StaInfoRxBitrate => { if let Some(rate) = attr .get_attr_handle::()? .get_attribute(Nl80211RateInfo::RateInfoBitrate32) { res.rx_bitrate = Some(rate.get_payload_as()?); } } Nl80211StaInfo::StaInfoTxBitrate => { let rate_info = attr.get_attr_handle::()?; if let Some(rate) = rate_info.get_attribute(Nl80211RateInfo::RateInfoBitrate32) { res.tx_bitrate = Some(rate.get_payload_as()?); } if let Some(ht_mcs) = rate_info.get_attribute(Nl80211RateInfo::RateInfoMcs) { res.ht_mcs = ht_mcs.get_payload_as().ok(); } if let Some(vht_mcs) = rate_info.get_attribute(Nl80211RateInfo::RateInfoVhtMcs) { res.vht_mcs = vht_mcs.get_payload_as().ok(); } if let Some(he_mcs) = rate_info.get_attribute(Nl80211RateInfo::RateInfoHeMcs) { res.he_mcs = he_mcs.get_payload_as().ok(); } if let Some(eht_mcs) = rate_info.get_attribute(Nl80211RateInfo::RateInfoEhtMcs) { res.eht_mcs = eht_mcs.get_payload_as().ok(); } } _ => (), } } } Ok(res) } } #[cfg(test)] mod tests_station { use super::*; use crate::attr::Nl80211Attr::AttrMac; use crate::attr::Nl80211Attr::AttrStaInfo; use neli::attr::AttrHandle; use neli::genl::{AttrType, Nlattr}; use neli::types::Buffer; fn new_attr(t: Nl80211Attr, d: Vec) -> Nlattr { Nlattr { nla_len: (4 + d.len()) as _, nla_type: AttrType { nla_nested: false, nla_network_order: true, nla_type: t, }, nla_payload: d.into(), } } #[test] fn test_parser() { let handler = vec![ new_attr(AttrMac, vec![46, 46, 46, 46, 46, 46]), new_attr( AttrStaInfo, vec![ 8, 0, 16, 0, 17, 27, 0, 0, 8, 0, 1, 0, 248, 2, 0, 0, 8, 0, 2, 0, 43, 98, 156, 29, 8, 0, 3, 0, 99, 123, 109, 1, 12, 0, 23, 0, 43, 98, 156, 29, 0, 0, 0, 0, 12, 0, 24, 0, 99, 123, 109, 1, 0, 0, 0, 0, 5, 0, 7, 0, 218, 0, 0, 0, 5, 0, 13, 0, 215, 0, 0, 0, 20, 0, 25, 0, 5, 0, 0, 0, 216, 0, 0, 0, 5, 0, 1, 0, 213, 0, 0, 0, 20, 0, 26, 0, 5, 0, 0, 0, 212, 0, 0, 0, 5, 0, 1, 0, 211, 0, 0, 0, 28, 0, 8, 0, 8, 0, 5, 0, 16, 4, 0, 0, 6, 0, 1, 0, 16, 4, 0, 0, 5, 0, 2, 0, 13, 0, 0, 0, 28, 0, 14, 0, 8, 0, 5, 0, 134, 1, 0, 0, 6, 0, 1, 0, 134, 1, 0, 0, 5, 0, 2, 0, 4, 0, 0, 0, 8, 0, 9, 0, 226, 128, 7, 0, 8, 0, 10, 0, 9, 170, 2, 0, 8, 0, 11, 0, 27, 130, 0, 0, 8, 0, 12, 0, 47, 0, 0, 0, 8, 0, 27, 0, 196, 160, 0, 0, 8, 0, 18, 0, 0, 0, 0, 0, 28, 0, 15, 0, 4, 0, 2, 0, 4, 0, 3, 0, 5, 0, 4, 0, 1, 0, 0, 0, 6, 0, 5, 0, 100, 0, 0, 0, 12, 0, 17, 0, 254, 0, 0, 0, 170, 0, 0, 0, 12, 0, 28, 0, 183, 3, 0, 0, 0, 0, 0, 0, 12, 0, 29, 0, 225, 254, 0, 0, 0, 0, 0, 0, 5, 0, 30, 0, 216, 0, 0, 0, 5, 0, 34, 0, 46, 0, 0, 0, 56, 8, 31, 0, 128, 0, 1, 0, 12, 0, 1, 0, 168, 103, 5, 0, 0, 0, 0, 0, 12, 0, 2, 0, 71, 169, 2, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 61, 39, 1, 0, 8, 0, 4, 0, 23, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 38, 56, 109, 1, 8, 0, 10, 0, 71, 169, 2, 0, 128, 0, 2, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 3, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 4, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 5, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 6, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 7, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 180, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 180, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 115, 64, 0, 0, 8, 0, 10, 0, 180, 0, 0, 0, 128, 0, 8, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 2, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 32, 1, 0, 0, 8, 0, 10, 0, 2, 0, 0, 0, 128, 0, 9, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 10, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 11, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 12, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 13, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 14, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 15, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 128, 0, 16, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 6, 0, 8, 0, 1, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 8, 0, 5, 0, 0, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 52, 0, 17, 0, 12, 0, 1, 0, 109, 25, 0, 0, 0, 0, 0, 0, 12, 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 12, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], ), ]; let station: Station = AttrHandle::new(handler.into_iter().collect()) .try_into() .unwrap(); let expected_station = Station { average_signal: Some(i8::from_le_bytes([215])), beacon_loss: Some(u32::from_le_bytes([0, 0, 0, 0])), bssid: Some(vec![46, 46, 46, 46, 46, 46]), connected_time: Some(u32::from_le_bytes([17, 27, 0, 0])), rx_bitrate: Some(u32::from_le_bytes([134, 1, 0, 0])), rx_packets: Some(u32::from_le_bytes([226, 128, 7, 0])), signal: Some(i8::from_le_bytes([218])), tx_bitrate: Some(u32::from_le_bytes([16, 4, 0, 0])), tx_failed: Some(u32::from_le_bytes([47, 0, 0, 0])), tx_packets: Some(u32::from_le_bytes([9, 170, 2, 0])), tx_retries: Some(u32::from_le_bytes([27, 130, 0, 0])), ht_mcs: Some(13), vht_mcs: None, he_mcs: None, eht_mcs: None, }; assert_eq!(station, expected_station) } }