1use netlink_packet_core::{
33 parse_string, parse_u16, parse_u32, parse_u64, parse_u8, DecodeError,
34 DefaultNla, Emitable, ErrorContext, Nla, NlaBuffer, NlasIterator,
35 Parseable, ParseableParametrized,
36};
37
38use crate::{
39 bytes::{write_u16, write_u32, write_u64},
40 scan::{Nla80211ScanFreqNlas, Nla80211ScanSsidNlas},
41 wiphy::Nl80211Commands,
42 Nl80211Band, Nl80211BandTypes, Nl80211BssInfo, Nl80211ChannelWidth,
43 Nl80211CipherSuit, Nl80211Command, Nl80211ExtFeature, Nl80211ExtFeatures,
44 Nl80211ExtendedCapability, Nl80211Features, Nl80211HtCapabilityMask,
45 Nl80211HtWiphyChannelType, Nl80211IfMode, Nl80211IfTypeExtCapa,
46 Nl80211IfTypeExtCapas, Nl80211IfaceComb, Nl80211IfaceFrameType,
47 Nl80211InterfaceType, Nl80211InterfaceTypes, Nl80211MloLink,
48 Nl80211ScanFlags, Nl80211SchedScanMatch, Nl80211SchedScanPlan,
49 Nl80211StationInfo, Nl80211SurveyInfo, Nl80211TransmitQueueStat,
50 Nl80211VhtCapability, Nl80211WowlanTriggersSupport,
51};
52
53const ETH_ALEN: usize = 6;
54
55struct MacAddressNlas(Vec<MacAddressNla>);
56
57impl std::ops::Deref for MacAddressNlas {
58 type Target = Vec<MacAddressNla>;
59
60 fn deref(&self) -> &Self::Target {
61 &self.0
62 }
63}
64
65impl From<&Vec<[u8; ETH_ALEN]>> for MacAddressNlas {
66 fn from(macs: &Vec<[u8; ETH_ALEN]>) -> Self {
67 let mut nlas = Vec::new();
68 for (i, mac) in macs.iter().enumerate() {
69 let nla = MacAddressNla {
70 index: i as u16,
71 mac: *mac,
72 };
73 nlas.push(nla);
74 }
75 MacAddressNlas(nlas)
76 }
77}
78
79impl From<MacAddressNlas> for Vec<[u8; ETH_ALEN]> {
80 fn from(macs: MacAddressNlas) -> Self {
81 let mut macs = macs;
82 macs.0.drain(..).map(|c| c.mac).collect()
83 }
84}
85
86impl MacAddressNlas {
87 pub fn parse(payload: &[u8]) -> Result<Self, DecodeError> {
88 let mut macs: Vec<MacAddressNla> = Vec::new();
89 for (index, nla) in NlasIterator::new(payload).enumerate() {
90 let error_msg = format!("Invalid NL80211_ATTR_MAC_ADDRS: {nla:?}");
91 let nla = &nla.context(error_msg.clone())?;
92 let mut mac = [0u8; ETH_ALEN];
93 mac.copy_from_slice(&nla.value()[..ETH_ALEN]);
94 macs.push(MacAddressNla {
95 index: index as u16,
96 mac,
97 });
98 }
99 Ok(Self(macs))
100 }
101}
102
103struct MacAddressNla {
104 index: u16,
105 mac: [u8; ETH_ALEN],
106}
107
108impl Nla for MacAddressNla {
109 fn value_len(&self) -> usize {
110 ETH_ALEN
111 }
112
113 fn emit_value(&self, buffer: &mut [u8]) {
114 buffer[..ETH_ALEN].copy_from_slice(&self.mac)
115 }
116
117 fn kind(&self) -> u16 {
118 self.index
119 }
120}
121
122const NL80211_ATTR_WIPHY: u16 = 1;
124const NL80211_ATTR_WIPHY_NAME: u16 = 2;
125const NL80211_ATTR_IFINDEX: u16 = 3;
126const NL80211_ATTR_IFNAME: u16 = 4;
127const NL80211_ATTR_IFTYPE: u16 = 5;
128const NL80211_ATTR_MAC: u16 = 6;
129const NL80211_ATTR_STA_INFO: u16 = 21;
144const NL80211_ATTR_WIPHY_BANDS: u16 = 22;
145const NL80211_ATTR_SUPPORTED_IFTYPES: u16 = 32;
155const NL80211_ATTR_WIPHY_FREQ: u16 = 38;
161const NL80211_ATTR_WIPHY_CHANNEL_TYPE: u16 = 39;
162const NL80211_ATTR_MAX_NUM_SCAN_SSIDS: u16 = 43;
166const NL80211_ATTR_SCAN_FREQUENCIES: u16 = 44;
167const NL80211_ATTR_SCAN_SSIDS: u16 = 45;
168const NL80211_ATTR_GENERATION: u16 = 46;
169const NL80211_ATTR_BSS: u16 = 47;
170const NL80211_ATTR_SUPPORTED_COMMANDS: u16 = 50;
173const NL80211_ATTR_SSID: u16 = 52;
175const NL80211_ATTR_MAX_SCAN_IE_LEN: u16 = 56;
179const NL80211_ATTR_CIPHER_SUITES: u16 = 57;
180const NL80211_ATTR_WIPHY_RETRY_SHORT: u16 = 61;
184const NL80211_ATTR_WIPHY_RETRY_LONG: u16 = 62;
185const NL80211_ATTR_WIPHY_FRAG_THRESHOLD: u16 = 63;
186const NL80211_ATTR_WIPHY_RTS_THRESHOLD: u16 = 64;
187const NL80211_ATTR_4ADDR: u16 = 83;
206const NL80211_ATTR_SURVEY_INFO: u16 = 84;
207const NL80211_ATTR_MAX_NUM_PMKIDS: u16 = 86;
209const NL80211_ATTR_WIPHY_COVERAGE_CLASS: u16 = 89;
212const NL80211_ATTR_WIPHY_TX_POWER_LEVEL: u16 = 98;
221const NL80211_ATTR_TX_FRAME_TYPES: u16 = 99;
222const NL80211_ATTR_RX_FRAME_TYPES: u16 = 100;
223const NL80211_ATTR_CONTROL_PORT_ETHERTYPE: u16 = 102;
226const NL80211_ATTR_SUPPORT_IBSS_RSN: u16 = 104;
228const NL80211_ATTR_WIPHY_ANTENNA_TX: u16 = 105;
229const NL80211_ATTR_WIPHY_ANTENNA_RX: u16 = 106;
230const NL80211_ATTR_OFFCHANNEL_TX_OK: u16 = 108;
232const NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: u16 = 111;
235const NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: u16 = 113;
237const NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: u16 = 114;
238const NL80211_ATTR_SUPPORT_MESH_AUTH: u16 = 115;
239const NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: u16 = 118;
242const NL80211_ATTR_SCHED_SCAN_INTERVAL: u16 = 119;
243const NL80211_ATTR_INTERFACE_COMBINATIONS: u16 = 120;
244const NL80211_ATTR_SOFTWARE_IFTYPES: u16 = 121;
245const NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: u16 = 123;
247const NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: u16 = 124;
248const NL80211_ATTR_SUPPORT_AP_UAPSD: u16 = 130;
254const NL80211_ATTR_ROAM_SUPPORT: u16 = 131;
255const NL80211_ATTR_SCHED_SCAN_MATCH: u16 = 132;
256const NL80211_ATTR_MAX_MATCH_SETS: u16 = 133;
257const NL80211_ATTR_TDLS_SUPPORT: u16 = 139;
263const NL80211_ATTR_TDLS_EXTERNAL_SETUP: u16 = 140;
264const NL80211_ATTR_FEATURE_FLAGS: u16 = 143;
267const NL80211_ATTR_PROBE_RESP_OFFLOAD: u16 = 144;
268const NL80211_ATTR_HT_CAPABILITY_MASK: u16 = 148;
272const NL80211_ATTR_WDEV: u16 = 153;
277const NL80211_ATTR_VHT_CAPABILITY: u16 = 157;
281const NL80211_ATTR_SCAN_FLAGS: u16 = 158;
282const NL80211_ATTR_CHANNEL_WIDTH: u16 = 159;
283const NL80211_ATTR_CENTER_FREQ1: u16 = 160;
284const NL80211_ATTR_CENTER_FREQ2: u16 = 161;
285const NL80211_ATTR_MAC_ADDRS: u16 = 166;
290const NL80211_ATTR_EXT_CAPA: u16 = 169;
293const NL80211_ATTR_EXT_CAPA_MASK: u16 = 170;
294const NL80211_ATTR_SPLIT_WIPHY_DUMP: u16 = 174;
298const NL80211_ATTR_VHT_CAPABILITY_MASK: u16 = 176;
300const NL80211_ATTR_MAX_CSA_COUNTERS: u16 = 206;
330const NL80211_ATTR_MAC_MASK: u16 = 215;
339const NL80211_ATTR_WIPHY_SELF_MANAGED_REG: u16 = 216;
340const NL80211_ATTR_EXT_FEATURES: u16 = 217;
341const NL80211_ATTR_SURVEY_RADIO_STATS: u16 = 218;
342const NL80211_ATTR_SCHED_SCAN_DELAY: u16 = 220;
344const NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS: u16 = 222;
346const NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL: u16 = 223;
347const NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS: u16 = 224;
348const NL80211_ATTR_SCHED_SCAN_PLANS: u16 = 225;
349const NL80211_ATTR_IFTYPE_EXT_CAPA: u16 = 230;
354const NL80211_ATTR_MEASUREMENT_DURATION: u16 = 235;
359const NL80211_ATTR_BANDS: u16 = 239;
363const NL80211_ATTR_SCHED_SCAN_MAX_REQS: u16 = 256;
380const NL80211_ATTR_TXQ_STATS: u16 = 265;
389const NL80211_ATTR_TXQ_LIMIT: u16 = 266;
390const NL80211_ATTR_TXQ_MEMORY_LIMIT: u16 = 267;
391const NL80211_ATTR_TXQ_QUANTUM: u16 = 268;
392const NL80211_ATTR_WIPHY_FREQ_OFFSET: u16 = 290;
414const NL80211_ATTR_MLO_LINKS: u16 = 312;
436const NL80211_ATTR_MAX_NUM_AKM_SUITES: u16 = 316;
441const NL80211_ATTR_EML_CAPABILITY: u16 = 317;
442const NL80211_ATTR_MLD_CAPA_AND_OPS: u16 = 318;
443const NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS: u16 = 323;
448#[derive(Debug, PartialEq, Eq, Clone)]
459#[non_exhaustive]
460pub enum Nl80211Attr {
461 Wiphy(u32),
462 WiphyName(String),
463 IfIndex(u32),
464 IfName(String),
465 IfType(Nl80211InterfaceType),
466 IfTypeExtCap(Vec<Nl80211IfTypeExtCapa>),
467 Mac([u8; ETH_ALEN]),
468 MacMask([u8; ETH_ALEN]),
469 MacAddrs(Vec<[u8; ETH_ALEN]>),
470 Wdev(u64),
471 Generation(u32),
472 Use4Addr(bool),
473 WiphyFreq(u32),
474 WiphyFreqOffset(u32),
475 WiphyChannelType(Nl80211HtWiphyChannelType),
476 ChannelWidth(Nl80211ChannelWidth),
477 CenterFreq1(u32),
478 CenterFreq2(u32),
479 WiphyTxPowerLevel(u32),
480 Ssid(String),
481 StationInfo(Vec<Nl80211StationInfo>),
482 SurveyInfo(Vec<Nl80211SurveyInfo>),
483 TransmitQueueStats(Vec<Nl80211TransmitQueueStat>),
484 TransmitQueueLimit(u32),
485 TransmitQueueMemoryLimit(u32),
486 TransmitQueueQuantum(u32),
487 MloLinks(Vec<Nl80211MloLink>),
488 WiphyRetryShort(u8),
489 WiphyRetryLong(u8),
490 WiphyFragThreshold(u32),
491 WiphyRtsThreshold(u32),
492 WiphyCoverageClass(u8),
493 MaxNumScanSsids(u8),
494 MaxNumSchedScanSsids(u8),
495 MaxScanIeLen(u16),
496 MaxSchedScanIeLen(u16),
497 MaxMatchSets(u8),
498 SupportIbssRsn,
499 SupportMeshAuth,
500 SupportApUapsd,
501 RoamSupport,
502 TdlsSupport,
503 TdlsExternalSetup,
504 CipherSuites(Vec<Nl80211CipherSuit>),
505 MaxNumPmkids(u8),
506 ControlPortEthertype,
507 WiphyAntennaAvailTx(u32),
508 WiphyAntennaAvailRx(u32),
509 ApProbeRespOffload(u32),
510 WiphyAntennaTx(u32),
511 WiphyAntennaRx(u32),
512 SupportedIftypes(Vec<Nl80211IfMode>),
513 WiphyBands(Vec<Nl80211Band>),
514 SplitWiphyDump,
518 SupportedCommand(Vec<Nl80211Command>),
519 MaxRemainOnChannelDuration(u32),
521 OffchannelTxOk,
522 SurveyRadioStats,
523 WowlanTriggersSupport(Vec<Nl80211WowlanTriggersSupport>),
524 SoftwareIftypes(Vec<Nl80211InterfaceType>),
525 Features(Nl80211Features),
526 ExtFeatures(Vec<Nl80211ExtFeature>),
527 InterfaceCombination(Vec<Nl80211IfaceComb>),
528 HtCapabilityMask(Nl80211HtCapabilityMask),
529 TxFrameTypes(Vec<Nl80211IfaceFrameType>),
530 RxFrameTypes(Vec<Nl80211IfaceFrameType>),
531 MaxNumSchedScanPlans(u32),
532 MaxScanPlanInterval(u32),
533 MaxScanPlanIterations(u32),
534 ExtCap(Nl80211ExtendedCapability),
535 ExtCapMask(Nl80211ExtendedCapability),
536 VhtCap(Nl80211VhtCapability),
537 VhtCapMask(Nl80211VhtCapability),
538 MaxCsaCounters(u8),
539 WiphySelfManagedReg,
540 SchedScanMaxReqs(u32),
541 EmlCapability(u16),
542 MldCapaAndOps(u16),
543 Bands(Nl80211BandTypes),
544 MaxNumAkmSuites(u16),
546 MaxHwTimestampPeers(u16),
551 Bss(Vec<Nl80211BssInfo>),
553 ScanSsids(Vec<String>),
554 ScanFlags(Nl80211ScanFlags),
555 MeasurementDuration(u16),
556 SchedScanInterval(u32),
558 SchedScanDelay(u32),
562 ScanFrequencies(Vec<u32>),
564 SchedScanMatch(Vec<Nl80211SchedScanMatch>),
574 SchedScanPlans(Vec<Nl80211SchedScanPlan>),
580 Other(DefaultNla),
581}
582
583impl Nla for Nl80211Attr {
584 fn value_len(&self) -> usize {
585 match self {
586 Self::IfIndex(_)
587 | Self::Wiphy(_)
588 | Self::IfType(_)
589 | Self::Generation(_)
590 | Self::WiphyFreq(_)
591 | Self::WiphyFreqOffset(_)
592 | Self::WiphyChannelType(_)
593 | Self::CenterFreq1(_)
594 | Self::CenterFreq2(_)
595 | Self::WiphyTxPowerLevel(_)
596 | Self::ChannelWidth(_)
597 | Self::WiphyFragThreshold(_)
598 | Self::WiphyRtsThreshold(_)
599 | Self::WiphyAntennaAvailTx(_)
600 | Self::WiphyAntennaAvailRx(_)
601 | Self::ApProbeRespOffload(_)
602 | Self::WiphyAntennaTx(_)
603 | Self::WiphyAntennaRx(_)
604 | Self::MaxNumSchedScanPlans(_)
605 | Self::MaxScanPlanInterval(_)
606 | Self::MaxScanPlanIterations(_)
607 | Self::SchedScanMaxReqs(_)
608 | Self::TransmitQueueLimit(_)
609 | Self::TransmitQueueMemoryLimit(_)
610 | Self::TransmitQueueQuantum(_)
611 | Self::SchedScanInterval(_)
612 | Self::SchedScanDelay(_) => 4,
613 Self::Wdev(_) => 8,
614 Self::IfName(s) | Self::Ssid(s) | Self::WiphyName(s) => s.len() + 1,
615 Self::Mac(_) | Self::MacMask(_) => ETH_ALEN,
616 Self::MacAddrs(s) => {
617 MacAddressNlas::from(s).as_slice().buffer_len()
618 }
619 Self::Use4Addr(_) => 1,
620 Self::WiphyRetryShort(_)
621 | Self::WiphyRetryLong(_)
622 | Self::WiphyCoverageClass(_)
623 | Self::MaxNumScanSsids(_)
624 | Self::MaxNumSchedScanSsids(_)
625 | Self::MaxMatchSets(_)
626 | Self::MaxNumPmkids(_) => 1,
627 Self::TransmitQueueStats(nlas) => nlas.as_slice().buffer_len(),
628 Self::StationInfo(nlas) => nlas.as_slice().buffer_len(),
629 Self::SurveyInfo(nlas) => nlas.as_slice().buffer_len(),
630 Self::MloLinks(links) => links.as_slice().buffer_len(),
631 Self::MaxScanIeLen(_) | Self::MaxSchedScanIeLen(_) => 2,
632 Self::SupportIbssRsn
633 | Self::SupportMeshAuth
634 | Self::SupportApUapsd
635 | Self::RoamSupport
636 | Self::TdlsSupport
637 | Self::TdlsExternalSetup
638 | Self::ControlPortEthertype
639 | Self::OffchannelTxOk
640 | Self::SurveyRadioStats
641 | Self::WiphySelfManagedReg => 0,
642 Self::CipherSuites(s) => 4 * s.len(),
643 Self::SupportedIftypes(s) => s.as_slice().buffer_len(),
644 Self::WiphyBands(s) => s.as_slice().buffer_len(),
645 Self::SplitWiphyDump => 0,
646 Self::SupportedCommand(s) => {
647 Nl80211Commands::from(s).as_slice().buffer_len()
648 }
649 Self::MaxRemainOnChannelDuration(_) => 4,
650 Self::WowlanTriggersSupport(s) => s.as_slice().buffer_len(),
651 Self::SoftwareIftypes(s) => {
652 Nl80211InterfaceTypes::from(s).as_slice().buffer_len()
653 }
654 Self::Features(_) => 4,
655 Self::ExtFeatures(_) => Nl80211ExtFeatures::LENGTH,
656 Self::InterfaceCombination(s) => s.as_slice().buffer_len(),
657 Self::HtCapabilityMask(_) => Nl80211HtCapabilityMask::LENGTH,
658 Self::TxFrameTypes(s) => s.as_slice().buffer_len(),
659 Self::RxFrameTypes(s) => s.as_slice().buffer_len(),
660 Self::ExtCap(v) => v.len(),
661 Self::ExtCapMask(v) => v.len(),
662 Self::VhtCap(v) => v.buffer_len(),
663 Self::VhtCapMask(v) => v.buffer_len(),
664 Self::MaxCsaCounters(_) => 1,
665 Self::IfTypeExtCap(s) => {
666 Nl80211IfTypeExtCapas::from(s).as_slice().buffer_len()
667 }
668 Self::EmlCapability(_)
669 | Self::MldCapaAndOps(_)
670 | Self::MaxNumAkmSuites(_)
671 | Self::MaxHwTimestampPeers(_)
672 | Self::MeasurementDuration(_) => 2,
673 Self::Bands(_) => Nl80211BandTypes::LENGTH,
674 Self::Bss(v) => v.as_slice().buffer_len(),
675 Self::ScanSsids(v) => {
676 Nla80211ScanSsidNlas::from(v).as_slice().buffer_len()
677 }
678 Self::ScanFlags(v) => v.buffer_len(),
679 Self::ScanFrequencies(v) => {
680 Nla80211ScanFreqNlas::from(v).as_slice().buffer_len()
681 }
682 Self::SchedScanMatch(v) => v.as_slice().buffer_len(),
683 Self::SchedScanPlans(v) => v.as_slice().buffer_len(),
684 Self::Other(attr) => attr.value_len(),
685 }
686 }
687
688 fn kind(&self) -> u16 {
689 match self {
690 Self::Wiphy(_) => NL80211_ATTR_WIPHY,
691 Self::WiphyName(_) => NL80211_ATTR_WIPHY_NAME,
692 Self::IfIndex(_) => NL80211_ATTR_IFINDEX,
693 Self::IfName(_) => NL80211_ATTR_IFNAME,
694 Self::IfType(_) => NL80211_ATTR_IFTYPE,
695 Self::Mac(_) => NL80211_ATTR_MAC,
696 Self::MacMask(_) => NL80211_ATTR_MAC_MASK,
697 Self::MacAddrs(_) => NL80211_ATTR_MAC_ADDRS,
698 Self::Wdev(_) => NL80211_ATTR_WDEV,
699 Self::Generation(_) => NL80211_ATTR_GENERATION,
700 Self::Use4Addr(_) => NL80211_ATTR_4ADDR,
701 Self::WiphyFreq(_) => NL80211_ATTR_WIPHY_FREQ,
702 Self::WiphyFreqOffset(_) => NL80211_ATTR_WIPHY_FREQ_OFFSET,
703 Self::WiphyChannelType(_) => NL80211_ATTR_WIPHY_CHANNEL_TYPE,
704 Self::ChannelWidth(_) => NL80211_ATTR_CHANNEL_WIDTH,
705 Self::CenterFreq1(_) => NL80211_ATTR_CENTER_FREQ1,
706 Self::CenterFreq2(_) => NL80211_ATTR_CENTER_FREQ2,
707 Self::WiphyTxPowerLevel(_) => NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
708 Self::Ssid(_) => NL80211_ATTR_SSID,
709 Self::StationInfo(_) => NL80211_ATTR_STA_INFO,
710 Self::SurveyInfo(_) => NL80211_ATTR_SURVEY_INFO,
711 Self::SurveyRadioStats => NL80211_ATTR_SURVEY_RADIO_STATS,
712 Self::TransmitQueueStats(_) => NL80211_ATTR_TXQ_STATS,
713 Self::TransmitQueueLimit(_) => NL80211_ATTR_TXQ_LIMIT,
714 Self::TransmitQueueMemoryLimit(_) => NL80211_ATTR_TXQ_MEMORY_LIMIT,
715 Self::TransmitQueueQuantum(_) => NL80211_ATTR_TXQ_QUANTUM,
716 Self::MloLinks(_) => NL80211_ATTR_MLO_LINKS,
717 Self::WiphyRetryShort(_) => NL80211_ATTR_WIPHY_RETRY_SHORT,
718 Self::WiphyRetryLong(_) => NL80211_ATTR_WIPHY_RETRY_LONG,
719 Self::WiphyFragThreshold(_) => NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
720 Self::WiphyRtsThreshold(_) => NL80211_ATTR_WIPHY_RTS_THRESHOLD,
721 Self::WiphyCoverageClass(_) => NL80211_ATTR_WIPHY_COVERAGE_CLASS,
722 Self::MaxNumScanSsids(_) => NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
723 Self::MaxNumSchedScanSsids(_) => {
724 NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS
725 }
726 Self::MaxScanIeLen(_) => NL80211_ATTR_MAX_SCAN_IE_LEN,
727 Self::MaxSchedScanIeLen(_) => NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
728 Self::MaxMatchSets(_) => NL80211_ATTR_MAX_MATCH_SETS,
729 Self::SupportIbssRsn => NL80211_ATTR_SUPPORT_IBSS_RSN,
730 Self::SupportMeshAuth => NL80211_ATTR_SUPPORT_MESH_AUTH,
731 Self::SupportApUapsd => NL80211_ATTR_SUPPORT_AP_UAPSD,
732 Self::RoamSupport => NL80211_ATTR_ROAM_SUPPORT,
733 Self::TdlsSupport => NL80211_ATTR_TDLS_SUPPORT,
734 Self::TdlsExternalSetup => NL80211_ATTR_TDLS_EXTERNAL_SETUP,
735 Self::CipherSuites(_) => NL80211_ATTR_CIPHER_SUITES,
736 Self::MaxNumPmkids(_) => NL80211_ATTR_MAX_NUM_PMKIDS,
737 Self::ControlPortEthertype => NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
738 Self::WiphyAntennaAvailTx(_) => NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
739 Self::WiphyAntennaAvailRx(_) => NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
740 Self::ApProbeRespOffload(_) => NL80211_ATTR_PROBE_RESP_OFFLOAD,
741 Self::WiphyAntennaTx(_) => NL80211_ATTR_WIPHY_ANTENNA_TX,
742 Self::WiphyAntennaRx(_) => NL80211_ATTR_WIPHY_ANTENNA_RX,
743 Self::SupportedIftypes(_) => NL80211_ATTR_SUPPORTED_IFTYPES,
744 Self::WiphyBands(_) => NL80211_ATTR_WIPHY_BANDS,
745 Self::SplitWiphyDump => NL80211_ATTR_SPLIT_WIPHY_DUMP,
746 Self::SupportedCommand(_) => NL80211_ATTR_SUPPORTED_COMMANDS,
747 Self::MaxRemainOnChannelDuration(_) => {
748 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION
749 }
750 Self::OffchannelTxOk => NL80211_ATTR_OFFCHANNEL_TX_OK,
751 Self::WowlanTriggersSupport(_) => {
752 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED
753 }
754 Self::SoftwareIftypes(_) => NL80211_ATTR_SOFTWARE_IFTYPES,
755 Self::Features(_) => NL80211_ATTR_FEATURE_FLAGS,
756 Self::ExtFeatures(_) => NL80211_ATTR_EXT_FEATURES,
757 Self::InterfaceCombination(_) => {
758 NL80211_ATTR_INTERFACE_COMBINATIONS
759 }
760 Self::HtCapabilityMask(_) => NL80211_ATTR_HT_CAPABILITY_MASK,
761 Self::TxFrameTypes(_) => NL80211_ATTR_TX_FRAME_TYPES,
762 Self::RxFrameTypes(_) => NL80211_ATTR_RX_FRAME_TYPES,
763 Self::MaxNumSchedScanPlans(_) => {
764 NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS
765 }
766 Self::MaxScanPlanInterval(_) => NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
767 Self::MaxScanPlanIterations(_) => {
768 NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS
769 }
770 Self::ExtCap(_) => NL80211_ATTR_EXT_CAPA,
771 Self::ExtCapMask(_) => NL80211_ATTR_EXT_CAPA_MASK,
772 Self::VhtCap(_) => NL80211_ATTR_VHT_CAPABILITY,
773 Self::VhtCapMask(_) => NL80211_ATTR_VHT_CAPABILITY_MASK,
774 Self::MaxCsaCounters(_) => NL80211_ATTR_MAX_CSA_COUNTERS,
775 Self::WiphySelfManagedReg => NL80211_ATTR_WIPHY_SELF_MANAGED_REG,
776 Self::SchedScanMaxReqs(_) => NL80211_ATTR_SCHED_SCAN_MAX_REQS,
777 Self::IfTypeExtCap(_) => NL80211_ATTR_IFTYPE_EXT_CAPA,
778 Self::EmlCapability(_) => NL80211_ATTR_EML_CAPABILITY,
779 Self::MldCapaAndOps(_) => NL80211_ATTR_MLD_CAPA_AND_OPS,
780 Self::Bands(_) => NL80211_ATTR_BANDS,
781 Self::MaxNumAkmSuites(_) => NL80211_ATTR_MAX_NUM_AKM_SUITES,
782 Self::MaxHwTimestampPeers(_) => NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS,
783 Self::Bss(_) => NL80211_ATTR_BSS,
784 Self::ScanSsids(_) => NL80211_ATTR_SCAN_SSIDS,
785 Self::ScanFlags(_) => NL80211_ATTR_SCAN_FLAGS,
786 Self::MeasurementDuration(_) => NL80211_ATTR_MEASUREMENT_DURATION,
787 Self::SchedScanInterval(_) => NL80211_ATTR_SCHED_SCAN_INTERVAL,
788 Self::SchedScanDelay(_) => NL80211_ATTR_SCHED_SCAN_DELAY,
789 Self::ScanFrequencies(_) => NL80211_ATTR_SCAN_FREQUENCIES,
790 Self::SchedScanMatch(_) => NL80211_ATTR_SCHED_SCAN_MATCH,
791 Self::SchedScanPlans(_) => NL80211_ATTR_SCHED_SCAN_PLANS,
792 Self::Other(attr) => attr.kind(),
793 }
794 }
795
796 fn emit_value(&self, buffer: &mut [u8]) {
797 match self {
798 Self::IfIndex(d)
799 | Self::Wiphy(d)
800 | Self::Generation(d)
801 | Self::WiphyFreq(d)
802 | Self::WiphyFreqOffset(d)
803 | Self::CenterFreq1(d)
804 | Self::CenterFreq2(d)
805 | Self::WiphyTxPowerLevel(d)
806 | Self::WiphyFragThreshold(d)
807 | Self::WiphyRtsThreshold(d)
808 | Self::WiphyAntennaAvailTx(d)
809 | Self::WiphyAntennaAvailRx(d)
810 | Self::ApProbeRespOffload(d)
811 | Self::WiphyAntennaTx(d)
812 | Self::WiphyAntennaRx(d)
813 | Self::MaxNumSchedScanPlans(d)
814 | Self::MaxScanPlanInterval(d)
815 | Self::MaxScanPlanIterations(d)
816 | Self::SchedScanMaxReqs(d)
817 | Self::TransmitQueueLimit(d)
818 | Self::TransmitQueueMemoryLimit(d)
819 | Self::TransmitQueueQuantum(d)
820 | Self::SchedScanInterval(d)
821 | Self::SchedScanDelay(d) => write_u32(buffer, *d),
822 Self::MaxScanIeLen(d) | Self::MaxSchedScanIeLen(d) => {
823 write_u16(buffer, *d)
824 }
825 Self::Wdev(d) => write_u64(buffer, *d),
826 Self::IfType(d) => write_u32(buffer, (*d).into()),
827 Self::Mac(s) | Self::MacMask(s) => buffer.copy_from_slice(s),
828 Self::MacAddrs(s) => {
829 MacAddressNlas::from(s).as_slice().emit(buffer)
830 }
831 Self::IfName(s) | Self::Ssid(s) | Self::WiphyName(s) => {
832 buffer[..s.len()].copy_from_slice(s.as_bytes());
833 buffer[s.len()] = 0;
834 }
835 Self::Use4Addr(d) => buffer[0] = *d as u8,
836 Self::SupportIbssRsn
837 | Self::SupportMeshAuth
838 | Self::SupportApUapsd
839 | Self::RoamSupport
840 | Self::TdlsSupport
841 | Self::TdlsExternalSetup
842 | Self::ControlPortEthertype
843 | Self::OffchannelTxOk
844 | Self::SurveyRadioStats
845 | Self::WiphySelfManagedReg => (),
846 Self::WiphyChannelType(d) => write_u32(buffer, (*d).into()),
847 Self::ChannelWidth(d) => write_u32(buffer, (*d).into()),
848 Self::StationInfo(nlas) => nlas.as_slice().emit(buffer),
849 Self::SurveyInfo(nlas) => nlas.as_slice().emit(buffer),
850 Self::TransmitQueueStats(nlas) => nlas.as_slice().emit(buffer),
851 Self::MloLinks(links) => links.as_slice().emit(buffer),
852 Self::WiphyRetryShort(d)
853 | Self::WiphyRetryLong(d)
854 | Self::WiphyCoverageClass(d)
855 | Self::MaxNumScanSsids(d)
856 | Self::MaxNumSchedScanSsids(d)
857 | Self::MaxMatchSets(d)
858 | Self::MaxNumPmkids(d) => buffer[0] = *d,
859 Self::CipherSuites(suits) => {
860 let nums: Vec<u32> =
861 suits.as_slice().iter().map(|s| u32::from(*s)).collect();
862 for (i, v) in nums.as_slice().iter().enumerate() {
863 buffer[i * 4..(i + 1) * 4]
864 .copy_from_slice(&v.to_ne_bytes());
865 }
866 }
867 Self::SupportedIftypes(s) => s.as_slice().emit(buffer),
868 Self::WiphyBands(s) => s.as_slice().emit(buffer),
869 Self::SplitWiphyDump => (),
870 Self::SupportedCommand(s) => {
871 Nl80211Commands::from(s).as_slice().emit(buffer)
872 }
873 Self::MaxRemainOnChannelDuration(d) => write_u32(buffer, *d),
874 Self::WowlanTriggersSupport(s) => s.as_slice().emit(buffer),
875 Self::SoftwareIftypes(s) => {
876 Nl80211InterfaceTypes::from(s).as_slice().emit(buffer)
877 }
878 Self::Features(d) => {
879 buffer.copy_from_slice(&d.bits().to_ne_bytes())
880 }
881 Self::ExtFeatures(s) => Nl80211ExtFeatures::from(s).emit(buffer),
882 Self::InterfaceCombination(s) => s.as_slice().emit(buffer),
883 Self::HtCapabilityMask(s) => s.emit(buffer),
884 Self::TxFrameTypes(s) => s.as_slice().emit(buffer),
885 Self::RxFrameTypes(s) => s.as_slice().emit(buffer),
886 Self::ExtCap(v) => v.emit(buffer),
887 Self::ExtCapMask(v) => v.emit(buffer),
888 Self::VhtCap(v) => v.emit(buffer),
889 Self::VhtCapMask(v) => v.emit(buffer),
890 Self::MaxCsaCounters(v) => buffer[0] = *v,
891 Self::IfTypeExtCap(s) => {
892 Nl80211IfTypeExtCapas::from(s).as_slice().emit(buffer)
893 }
894 Self::EmlCapability(d)
895 | Self::MldCapaAndOps(d)
896 | Self::MaxNumAkmSuites(d)
897 | Self::MaxHwTimestampPeers(d)
898 | Self::MeasurementDuration(d) => write_u16(buffer, *d),
899 Self::Bands(v) => v.emit(buffer),
900 Self::Bss(v) => v.as_slice().emit(buffer),
901 Self::ScanSsids(v) => {
902 Nla80211ScanSsidNlas::from(v).as_slice().emit(buffer)
903 }
904 Self::ScanFlags(v) => v.emit(buffer),
905 Self::ScanFrequencies(v) => {
906 Nla80211ScanFreqNlas::from(v).as_slice().emit(buffer)
907 }
908 Self::SchedScanMatch(v) => v.as_slice().emit(buffer),
909 Self::SchedScanPlans(v) => v.as_slice().emit(buffer),
910 Self::Other(attr) => attr.emit(buffer),
911 }
912 }
913}
914
915impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Nl80211Attr {
916 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
917 let payload = buf.value();
918 Ok(match buf.kind() {
919 NL80211_ATTR_IFINDEX => {
920 let err_msg =
921 format!("Invalid NL80211_ATTR_IFINDEX value {payload:?}");
922 Self::IfIndex(parse_u32(payload).context(err_msg)?)
923 }
924 NL80211_ATTR_WIPHY => {
925 let err_msg =
926 format!("Invalid NL80211_ATTR_WIPHY value {payload:?}");
927 Self::Wiphy(parse_u32(payload).context(err_msg)?)
928 }
929 NL80211_ATTR_WIPHY_NAME => {
930 let err_msg = format!(
931 "Invalid NL80211_ATTR_WIPHY_NAME value {payload:?}"
932 );
933 Self::WiphyName(parse_string(payload).context(err_msg)?)
934 }
935 NL80211_ATTR_IFNAME => {
936 let err_msg =
937 format!("Invalid NL80211_ATTR_IFNAME value {payload:?}");
938 Self::IfName(parse_string(payload).context(err_msg)?)
939 }
940 NL80211_ATTR_IFTYPE => {
941 Self::IfType(Nl80211InterfaceType::parse(payload)?)
942 }
943 NL80211_ATTR_WDEV => {
944 let err_msg =
945 format!("Invalid NL80211_ATTR_WDEV value {payload:?}");
946 Self::Wdev(parse_u64(payload).context(err_msg)?)
947 }
948 NL80211_ATTR_MAC => Self::Mac(if payload.len() == ETH_ALEN {
949 let mut ret = [0u8; ETH_ALEN];
950 ret.copy_from_slice(&payload[..ETH_ALEN]);
951 ret
952 } else {
953 return Err(format!(
954 "Invalid length of NL80211_ATTR_MAC, \
955 expected length {ETH_ALEN} got {payload:?}"
956 )
957 .into());
958 }),
959 NL80211_ATTR_MAC_MASK => {
960 Self::MacMask(if payload.len() == ETH_ALEN {
961 let mut ret = [0u8; ETH_ALEN];
962 ret.copy_from_slice(&payload[..ETH_ALEN]);
963 ret
964 } else {
965 return Err(format!(
966 "Invalid length of NL80211_ATTR_MAC_MASK, \
967 expected length {ETH_ALEN} got {payload:?}"
968 )
969 .into());
970 })
971 }
972 NL80211_ATTR_MAC_ADDRS => {
973 Self::MacAddrs(MacAddressNlas::parse(payload)?.into())
974 }
975 NL80211_ATTR_GENERATION => {
976 let err_msg = format!(
977 "Invalid NL80211_ATTR_GENERATION value {payload:?}"
978 );
979 Self::Generation(parse_u32(payload).context(err_msg)?)
980 }
981 NL80211_ATTR_BSS => {
982 let err_msg =
983 format!("Invalid NL80211_ATTR_BSS value {payload:?}");
984 let mut nlas = Vec::new();
985 for nla in NlasIterator::new(payload) {
986 let nla = &nla.context(err_msg.clone())?;
987 nlas.push(Nl80211BssInfo::parse(nla)?);
988 }
989 Self::Bss(nlas)
990 }
991 NL80211_ATTR_4ADDR => {
992 let err_msg =
993 format!("Invalid NL80211_ATTR_4ADDR value {payload:?}");
994 Self::Use4Addr(parse_u8(payload).context(err_msg)? > 0)
995 }
996 NL80211_ATTR_WIPHY_FREQ => {
997 let err_msg = format!(
998 "Invalid NL80211_ATTR_WIPHY_FREQ value {payload:?}"
999 );
1000 Self::WiphyFreq(parse_u32(payload).context(err_msg)?)
1001 }
1002 NL80211_ATTR_WIPHY_FREQ_OFFSET => {
1003 let err_msg = format!(
1004 "Invalid NL80211_ATTR_WIPHY_FREQ_OFFSET value {payload:?}"
1005 );
1006 Self::WiphyFreqOffset(parse_u32(payload).context(err_msg)?)
1007 }
1008 NL80211_ATTR_WIPHY_CHANNEL_TYPE => {
1009 let err_msg = format!(
1010 "Invalid NL80211_ATTR_WIPHY_CHANNEL_TYPE value {payload:?}"
1011 );
1012 Self::WiphyChannelType(
1013 parse_u32(payload).context(err_msg)?.into(),
1014 )
1015 }
1016 NL80211_ATTR_CHANNEL_WIDTH => {
1017 let err_msg = format!(
1018 "Invalid NL80211_ATTR_CHANNEL_WIDTH value {payload:?}"
1019 );
1020 Self::ChannelWidth(parse_u32(payload).context(err_msg)?.into())
1021 }
1022 NL80211_ATTR_CENTER_FREQ1 => {
1023 let err_msg = format!(
1024 "Invalid NL80211_ATTR_CENTER_FREQ1 value {payload:?}"
1025 );
1026 Self::CenterFreq1(parse_u32(payload).context(err_msg)?)
1027 }
1028 NL80211_ATTR_CENTER_FREQ2 => {
1029 let err_msg = format!(
1030 "Invalid NL80211_ATTR_CENTER_FREQ2 value {payload:?}"
1031 );
1032 Self::CenterFreq2(parse_u32(payload).context(err_msg)?)
1033 }
1034 NL80211_ATTR_WIPHY_TX_POWER_LEVEL => {
1035 let err_msg = format!(
1036 "Invalid NL80211_ATTR_WIPHY_TX_POWER_LEVEL value {payload:?}"
1037 );
1038 Self::WiphyTxPowerLevel(parse_u32(payload).context(err_msg)?)
1039 }
1040 NL80211_ATTR_SSID => {
1041 let err_msg =
1042 format!("Invalid NL80211_ATTR_SSID value {payload:?}");
1043 Self::Ssid(parse_string(payload).context(err_msg)?)
1044 }
1045 NL80211_ATTR_STA_INFO => {
1046 let err_msg =
1047 format!("Invalid NL80211_ATTR_STA_INFO value {payload:?}");
1048 let mut nlas = Vec::new();
1049 for nla in NlasIterator::new(payload) {
1050 let nla = &nla.context(err_msg.clone())?;
1051 nlas.push(
1052 Nl80211StationInfo::parse(nla)
1053 .context(err_msg.clone())?,
1054 );
1055 }
1056 Self::StationInfo(nlas)
1057 }
1058 NL80211_ATTR_SURVEY_INFO => {
1059 let err_msg = format!(
1060 "Invalid NL80211_ATTR_SURVEY_INFO value {payload:?}"
1061 );
1062 let mut nlas = Vec::new();
1063 for nla in NlasIterator::new(payload) {
1064 let nla = &nla.context(err_msg.clone())?;
1065 nlas.push(
1066 Nl80211SurveyInfo::parse(nla)
1067 .context(err_msg.clone())?,
1068 );
1069 }
1070 Self::SurveyInfo(nlas)
1071 }
1072 NL80211_ATTR_SURVEY_RADIO_STATS => Self::SurveyRadioStats,
1073 NL80211_ATTR_TXQ_STATS => {
1074 let err_msg =
1075 format!("Invalid NL80211_ATTR_TXQ_STATS value {payload:?}");
1076 let mut nlas = Vec::new();
1077 for nla in NlasIterator::new(payload) {
1078 let nla = &nla.context(err_msg.clone())?;
1079 nlas.push(
1080 Nl80211TransmitQueueStat::parse(nla)
1081 .context(err_msg.clone())?,
1082 );
1083 }
1084 Self::TransmitQueueStats(nlas)
1085 }
1086 NL80211_ATTR_TXQ_LIMIT => {
1087 Self::TransmitQueueLimit(parse_u32(payload).context(
1088 format!("Invalid NL80211_ATTR_TXQ_LIMIT {payload:?}"),
1089 )?)
1090 }
1091 NL80211_ATTR_TXQ_MEMORY_LIMIT => Self::TransmitQueueMemoryLimit(
1092 parse_u32(payload).context(format!(
1093 "Invalid NL80211_ATTR_TXQ_MEMORY_LIMIT {payload:?}"
1094 ))?,
1095 ),
1096 NL80211_ATTR_TXQ_QUANTUM => {
1097 Self::TransmitQueueQuantum(parse_u32(payload).context(
1098 format!("Invalid NL80211_ATTR_TXQ_QUANTUM {payload:?}"),
1099 )?)
1100 }
1101 NL80211_ATTR_MLO_LINKS => {
1102 let err_msg =
1103 format!("Invalid NL80211_ATTR_MLO_LINKS value {payload:?}");
1104 let mut links = Vec::new();
1105 for nla in NlasIterator::new(payload) {
1106 let nla = &nla.context(err_msg.clone())?;
1107 links.push(
1108 Nl80211MloLink::parse(nla).context(err_msg.clone())?,
1109 );
1110 }
1111 Self::MloLinks(links)
1112 }
1113 NL80211_ATTR_WIPHY_RETRY_SHORT => {
1114 let err_msg = format!(
1115 "Invalid NL80211_ATTR_WIPHY_RETRY_SHORT value {payload:?}"
1116 );
1117 Self::WiphyRetryShort(parse_u8(payload).context(err_msg)?)
1118 }
1119 NL80211_ATTR_WIPHY_RETRY_LONG => {
1120 let err_msg = format!(
1121 "Invalid NL80211_ATTR_WIPHY_RETRY_LONG value {payload:?}"
1122 );
1123 Self::WiphyRetryLong(parse_u8(payload).context(err_msg)?)
1124 }
1125 NL80211_ATTR_WIPHY_FRAG_THRESHOLD => {
1126 let err_msg = format!(
1127 "Invalid NL80211_ATTR_WIPHY_FRAG_THRESHOLD value {payload:?}"
1128 );
1129 Self::WiphyFragThreshold(parse_u32(payload).context(err_msg)?)
1130 }
1131 NL80211_ATTR_WIPHY_RTS_THRESHOLD => {
1132 let err_msg = format!(
1133 "Invalid NL80211_ATTR_WIPHY_RTS_THRESHOLD value {payload:?}"
1134 );
1135 Self::WiphyRtsThreshold(parse_u32(payload).context(err_msg)?)
1136 }
1137 NL80211_ATTR_WIPHY_COVERAGE_CLASS => {
1138 let err_msg = format!(
1139 "Invalid NL80211_ATTR_WIPHY_COVERAGE_CLASS value {payload:?}"
1140 );
1141 Self::WiphyCoverageClass(parse_u8(payload).context(err_msg)?)
1142 }
1143 NL80211_ATTR_MAX_NUM_SCAN_SSIDS => {
1144 let err_msg = format!(
1145 "Invalid NL80211_ATTR_MAX_NUM_SCAN_SSIDS value {payload:?}"
1146 );
1147 Self::MaxNumScanSsids(parse_u8(payload).context(err_msg)?)
1148 }
1149 NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS => {
1150 let err_msg = format!(
1151 "Invalid NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS value {payload:?}"
1152 );
1153 Self::MaxNumSchedScanSsids(parse_u8(payload).context(err_msg)?)
1154 }
1155 NL80211_ATTR_MAX_SCAN_IE_LEN => {
1156 let err_msg = format!(
1157 "Invalid NL80211_ATTR_MAX_SCAN_IE_LEN value {payload:?}"
1158 );
1159 Self::MaxScanIeLen(parse_u16(payload).context(err_msg)?)
1160 }
1161 NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN => {
1162 let err_msg = format!(
1163 "Invalid NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN value {payload:?}"
1164 );
1165 Self::MaxSchedScanIeLen(parse_u16(payload).context(err_msg)?)
1166 }
1167 NL80211_ATTR_MAX_MATCH_SETS => {
1168 let err_msg = format!(
1169 "Invalid NL80211_ATTR_MAX_MATCH_SETS value {payload:?}"
1170 );
1171 Self::MaxMatchSets(parse_u8(payload).context(err_msg)?)
1172 }
1173 NL80211_ATTR_SUPPORT_IBSS_RSN => Self::SupportIbssRsn,
1174 NL80211_ATTR_SUPPORT_MESH_AUTH => Self::SupportMeshAuth,
1175 NL80211_ATTR_SUPPORT_AP_UAPSD => Self::SupportApUapsd,
1176 NL80211_ATTR_ROAM_SUPPORT => Self::RoamSupport,
1177 NL80211_ATTR_TDLS_SUPPORT => Self::TdlsSupport,
1178 NL80211_ATTR_TDLS_EXTERNAL_SETUP => Self::TdlsExternalSetup,
1179 NL80211_ATTR_CIPHER_SUITES => {
1180 let err_msg = format!(
1181 "Invalid NL80211_ATTR_CIPHER_SUITES value {payload:?}"
1182 );
1183 let mut suits = Vec::new();
1184 for i in 0..(payload.len() / 4) {
1185 suits.push(
1186 parse_u32(&payload[i * 4..(i + 1) * 4])
1187 .context(err_msg.clone())?
1188 .into(),
1189 );
1190 }
1191 Self::CipherSuites(suits)
1192 }
1193 NL80211_ATTR_MAX_NUM_PMKIDS => {
1194 let err_msg = format!(
1195 "Invalid NL80211_ATTR_MAX_NUM_PMKIDS value {payload:?}"
1196 );
1197 Self::MaxNumPmkids(parse_u8(payload).context(err_msg)?)
1198 }
1199 NL80211_ATTR_CONTROL_PORT_ETHERTYPE => Self::ControlPortEthertype,
1200 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX => {
1201 let err_msg = format!(
1202 "Invalid NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX value {payload:?}"
1203 );
1204 Self::WiphyAntennaAvailTx(parse_u32(payload).context(err_msg)?)
1205 }
1206 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX => {
1207 let err_msg = format!(
1208 "Invalid NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX value {payload:?}"
1209 );
1210 Self::WiphyAntennaAvailRx(parse_u32(payload).context(err_msg)?)
1211 }
1212 NL80211_ATTR_PROBE_RESP_OFFLOAD => {
1213 let err_msg = format!(
1214 "Invalid NL80211_ATTR_PROBE_RESP_OFFLOAD value {payload:?}"
1215 );
1216 Self::ApProbeRespOffload(parse_u32(payload).context(err_msg)?)
1217 }
1218 NL80211_ATTR_WIPHY_ANTENNA_TX => {
1219 let err_msg = format!(
1220 "Invalid NL80211_ATTR_WIPHY_ANTENNA_TX value {payload:?}"
1221 );
1222 Self::WiphyAntennaTx(parse_u32(payload).context(err_msg)?)
1223 }
1224 NL80211_ATTR_WIPHY_ANTENNA_RX => {
1225 let err_msg = format!(
1226 "Invalid NL80211_ATTR_WIPHY_ANTENNA_RX value {payload:?}"
1227 );
1228 Self::WiphyAntennaRx(parse_u32(payload).context(err_msg)?)
1229 }
1230 NL80211_ATTR_SUPPORTED_IFTYPES => {
1231 let err_msg = format!(
1232 "Invalid NL80211_ATTR_SUPPORTED_IFTYPES value {payload:?}"
1233 );
1234 let mut nlas = Vec::new();
1235 for nla in NlasIterator::new(payload) {
1236 let nla = &nla.context(err_msg.clone())?;
1237 nlas.push(
1238 Nl80211IfMode::parse(nla).context(err_msg.clone())?,
1239 );
1240 }
1241 Self::SupportedIftypes(nlas)
1242 }
1243 NL80211_ATTR_WIPHY_BANDS => {
1244 let mut nlas = Vec::new();
1245 for nla in NlasIterator::new(payload) {
1246 let err_msg = format!(
1247 "Invalid NL80211_ATTR_WIPHY_BANDS value {nla:?}"
1248 );
1249 let nla = &nla.context(err_msg.clone())?;
1250 nlas.push(Nl80211Band::parse(nla)?);
1251 }
1252 Self::WiphyBands(nlas)
1253 }
1254 NL80211_ATTR_SPLIT_WIPHY_DUMP => Self::SplitWiphyDump,
1255 NL80211_ATTR_SUPPORTED_COMMANDS => {
1256 Self::SupportedCommand(Nl80211Commands::parse(payload)?.into())
1257 }
1258 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION => {
1259 let err_msg = format!(
1260 "Invalid \
1261 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION {payload:?}"
1262 );
1263 Self::MaxRemainOnChannelDuration(
1264 parse_u32(payload).context(err_msg)?,
1265 )
1266 }
1267 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED => {
1268 let mut nlas = Vec::new();
1269 for nla in NlasIterator::new(payload) {
1270 let err_msg = format!(
1271 "Invalid NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED \
1272 value {nla:?}"
1273 );
1274 let nla = &nla.context(err_msg.clone())?;
1275 nlas.push(Nl80211WowlanTriggersSupport::parse(nla)?);
1276 }
1277 Self::WowlanTriggersSupport(nlas)
1278 }
1279 NL80211_ATTR_OFFCHANNEL_TX_OK => Self::OffchannelTxOk,
1280 NL80211_ATTR_SOFTWARE_IFTYPES => Self::SoftwareIftypes(
1281 Nl80211InterfaceTypes::parse(
1282 payload,
1283 "NL80211_ATTR_SOFTWARE_IFTYPES",
1284 )?
1285 .0,
1286 ),
1287 NL80211_ATTR_FEATURE_FLAGS => Self::Features(
1288 Nl80211Features::from_bits_retain(parse_u32(payload).context(
1289 format!("Invalid NL80211_ATTR_FEATURE_FLAGS {payload:?}"),
1290 )?),
1291 ),
1292 NL80211_ATTR_EXT_FEATURES => {
1293 Self::ExtFeatures(Nl80211ExtFeatures::parse(payload)?.0)
1294 }
1295 NL80211_ATTR_INTERFACE_COMBINATIONS => {
1296 let mut nlas = Vec::new();
1297 for (index, nla) in NlasIterator::new(payload).enumerate() {
1298 let err_msg = format!(
1299 "Invalid NL80211_ATTR_INTERFACE_COMBINATIONS \
1300 value {nla:?}"
1301 );
1302 let nla = &nla.context(err_msg.clone())?;
1303 nlas.push(Nl80211IfaceComb::parse_with_param(
1304 nla,
1305 index as u16,
1306 )?);
1307 }
1308 Self::InterfaceCombination(nlas)
1309 }
1310 NL80211_ATTR_HT_CAPABILITY_MASK => {
1311 Self::HtCapabilityMask(Nl80211HtCapabilityMask::new(payload))
1312 }
1313 NL80211_ATTR_RX_FRAME_TYPES => {
1314 let mut nlas = Vec::new();
1315 for nla in NlasIterator::new(payload) {
1316 let err_msg = format!(
1317 "Invalid NL80211_ATTR_RX_FRAME_TYPES value {nla:?}"
1318 );
1319 let nla = &nla.context(err_msg.clone())?;
1320 nlas.push(Nl80211IfaceFrameType::parse(nla)?);
1321 }
1322 Self::RxFrameTypes(nlas)
1323 }
1324 NL80211_ATTR_TX_FRAME_TYPES => {
1325 let mut nlas = Vec::new();
1326 for nla in NlasIterator::new(payload) {
1327 let err_msg = format!(
1328 "Invalid NL80211_ATTR_RX_FRAME_TYPES value {nla:?}"
1329 );
1330 let nla = &nla.context(err_msg.clone())?;
1331 nlas.push(Nl80211IfaceFrameType::parse(nla)?);
1332 }
1333 Self::TxFrameTypes(nlas)
1334 }
1335 NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS => {
1336 Self::MaxNumSchedScanPlans(parse_u32(payload).context(
1337 format!(
1338 "Invalid NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS \
1339 {payload:?}"
1340 ),
1341 )?)
1342 }
1343 NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL => Self::MaxScanPlanInterval(
1344 parse_u32(payload).context(format!(
1345 "Invalid NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL \
1346 {payload:?}"
1347 ))?,
1348 ),
1349 NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS => {
1350 Self::MaxScanPlanIterations(parse_u32(payload).context(
1351 format!(
1352 "Invalid NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS \
1353 {payload:?}"
1354 ),
1355 )?)
1356 }
1357 NL80211_ATTR_EXT_CAPA => {
1358 Self::ExtCap(Nl80211ExtendedCapability::new(payload))
1359 }
1360 NL80211_ATTR_EXT_CAPA_MASK => {
1361 Self::ExtCapMask(Nl80211ExtendedCapability::new(payload))
1362 }
1363 NL80211_ATTR_VHT_CAPABILITY => {
1364 Self::VhtCap(Nl80211VhtCapability::parse(payload)?)
1365 }
1366 NL80211_ATTR_VHT_CAPABILITY_MASK => {
1367 Self::VhtCapMask(Nl80211VhtCapability::parse(payload)?)
1368 }
1369 NL80211_ATTR_MAX_CSA_COUNTERS => {
1370 Self::MaxCsaCounters(parse_u8(payload).context(format!(
1371 "Invalid NL80211_ATTR_MAX_CSA_COUNTERS {payload:?}"
1372 ))?)
1373 }
1374 NL80211_ATTR_WIPHY_SELF_MANAGED_REG => Self::WiphySelfManagedReg,
1375 NL80211_ATTR_SCHED_SCAN_MAX_REQS => {
1376 Self::SchedScanMaxReqs(parse_u32(payload).context(format!(
1377 "Invalid NL80211_ATTR_SCHED_SCAN_MAX_REQS {payload:?}"
1378 ))?)
1379 }
1380 NL80211_ATTR_IFTYPE_EXT_CAPA => {
1381 Self::IfTypeExtCap(Nl80211IfTypeExtCapas::parse(buf)?.into())
1382 }
1383 NL80211_ATTR_EML_CAPABILITY => {
1384 Self::EmlCapability(parse_u16(payload).context(format!(
1385 "Invalid NL80211_ATTR_EML_CAPABILITY {payload:?}"
1386 ))?)
1387 }
1388 NL80211_ATTR_MLD_CAPA_AND_OPS => {
1389 Self::MldCapaAndOps(parse_u16(payload).context(format!(
1390 "Invalid NL80211_ATTR_MLD_CAPA_AND_OPS {payload:?}"
1391 ))?)
1392 }
1393 NL80211_ATTR_BANDS => {
1394 Self::Bands(Nl80211BandTypes::parse(payload)?)
1395 }
1396 NL80211_ATTR_MAX_NUM_AKM_SUITES => {
1397 Self::MaxNumAkmSuites(parse_u16(payload).context(format!(
1398 "Invalid NL80211_ATTR_MAX_NUM_AKM_SUITES {payload:?}"
1399 ))?)
1400 }
1401 NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS => Self::MaxHwTimestampPeers(
1402 parse_u16(payload).context(format!(
1403 "Invalid NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS {payload:?}"
1404 ))?,
1405 ),
1406 NL80211_ATTR_SCAN_SSIDS => {
1407 Self::ScanSsids(Nla80211ScanSsidNlas::parse(payload)?.into())
1408 }
1409 NL80211_ATTR_SCAN_FLAGS => {
1410 Self::ScanFlags(Nl80211ScanFlags::parse(payload)?)
1411 }
1412 NL80211_ATTR_MEASUREMENT_DURATION => {
1413 let err_msg = format!(
1414 "Invalid NL80211_ATTR_MEASUREMENT_DURATION value {payload:?}"
1415 );
1416 Self::MeasurementDuration(parse_u16(payload).context(err_msg)?)
1417 }
1418 NL80211_ATTR_SCHED_SCAN_INTERVAL => {
1419 let err_msg = format!(
1420 "Invalid NL80211_ATTR_SCHED_SCAN_INTERVAL value {payload:?}"
1421 );
1422 Self::SchedScanInterval(parse_u32(payload).context(err_msg)?)
1423 }
1424 NL80211_ATTR_SCHED_SCAN_DELAY => {
1425 let err_msg = format!(
1426 "Invalid NL80211_ATTR_SCHED_SCAN_DELAY value {payload:?}"
1427 );
1428 Self::SchedScanDelay(parse_u32(payload).context(err_msg)?)
1429 }
1430 NL80211_ATTR_SCAN_FREQUENCIES => Self::ScanFrequencies(
1431 Nla80211ScanFreqNlas::parse(payload)?.into(),
1432 ),
1433 NL80211_ATTR_SCHED_SCAN_MATCH => {
1434 let err_msg = format!(
1435 "Invalid NL80211_ATTR_SCHED_SCAN_MATCH value {payload:?}"
1436 );
1437 let mut nlas = Vec::new();
1438 for nla in NlasIterator::new(payload) {
1439 let nla = &nla.context(err_msg.clone())?;
1440 nlas.push(Nl80211SchedScanMatch::parse(nla)?);
1441 }
1442 Self::SchedScanMatch(nlas)
1443 }
1444 NL80211_ATTR_SCHED_SCAN_PLANS => {
1445 let err_msg = format!(
1446 "Invalid NL80211_ATTR_SCHED_SCAN_PLANS value {payload:?}"
1447 );
1448 let mut nlas = Vec::new();
1449 for nla in NlasIterator::new(payload) {
1450 let nla = &nla.context(err_msg.clone())?;
1451 nlas.push(Nl80211SchedScanPlan::parse(nla)?);
1452 }
1453 Self::SchedScanPlans(nlas)
1454 }
1455 _ => Self::Other(
1456 DefaultNla::parse(buf).context("invalid NLA (unknown kind)")?,
1457 ),
1458 })
1459 }
1460}