@@ -38,17 +38,21 @@ use netlink_packet_utils::{
38
38
39
39
use crate :: {
40
40
bytes:: { write_u16, write_u32, write_u64} ,
41
+ scan:: { Nla80211ScanFreqNlas , Nla80211ScanSsidNlas } ,
41
42
wiphy:: Nl80211Commands ,
42
43
Nl80211Band , Nl80211BandTypes , Nl80211BssInfo , Nl80211ChannelWidth ,
43
44
Nl80211CipherSuit , Nl80211Command , Nl80211ExtFeature , Nl80211ExtFeatures ,
44
45
Nl80211ExtendedCapability , Nl80211Features , Nl80211HtCapabilityMask ,
45
46
Nl80211HtWiphyChannelType , Nl80211IfMode , Nl80211IfTypeExtCapa ,
46
47
Nl80211IfTypeExtCapas , Nl80211IfaceComb , Nl80211IfaceFrameType ,
47
48
Nl80211InterfaceType , Nl80211InterfaceTypes , Nl80211MloLink ,
49
+ Nl80211ScanFlags , Nl80211SchedScanMatch , Nl80211SchedScanPlan ,
48
50
Nl80211StationInfo , Nl80211TransmitQueueStat , Nl80211VhtCapability ,
49
51
Nl80211WowlanTrigersSupport ,
50
52
} ;
51
53
54
+ const ETH_ALEN : usize = 6 ;
55
+
52
56
struct MacAddressNlas ( Vec < MacAddressNla > ) ;
53
57
54
58
impl std:: ops:: Deref for MacAddressNlas {
@@ -160,8 +164,8 @@ const NL80211_ATTR_WIPHY_CHANNEL_TYPE: u16 = 39;
160
164
// const NL80211_ATTR_MGMT_SUBTYPE:u16 = 41;
161
165
// const NL80211_ATTR_IE:u16 = 42;
162
166
const NL80211_ATTR_MAX_NUM_SCAN_SSIDS : u16 = 43 ;
163
- // const NL80211_ATTR_SCAN_FREQUENCIES:u16 = 44;
164
- // const NL80211_ATTR_SCAN_SSIDS:u16 = 45;
167
+ const NL80211_ATTR_SCAN_FREQUENCIES : u16 = 44 ;
168
+ const NL80211_ATTR_SCAN_SSIDS : u16 = 45 ;
165
169
const NL80211_ATTR_GENERATION : u16 = 46 ;
166
170
const NL80211_ATTR_BSS : u16 = 47 ;
167
171
// const NL80211_ATTR_REG_INITIATOR:u16 = 48;
@@ -236,7 +240,7 @@ const NL80211_ATTR_SUPPORT_MESH_AUTH: u16 = 115;
236
240
// const NL80211_ATTR_STA_PLINK_STATE:u16 = 116;
237
241
// const NL80211_ATTR_WOWLAN_TRIGGERS:u16 = 117;
238
242
const NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED : u16 = 118 ;
239
- // const NL80211_ATTR_SCHED_SCAN_INTERVAL:u16 = 119;
243
+ const NL80211_ATTR_SCHED_SCAN_INTERVAL : u16 = 119 ;
240
244
const NL80211_ATTR_INTERFACE_COMBINATIONS : u16 = 120 ;
241
245
const NL80211_ATTR_SOFTWARE_IFTYPES : u16 = 121 ;
242
246
// const NL80211_ATTR_REKEY_DATA:u16 = 122;
@@ -249,7 +253,7 @@ const NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: u16 = 124;
249
253
// const NL80211_ATTR_STA_WME:u16 = 129;
250
254
const NL80211_ATTR_SUPPORT_AP_UAPSD : u16 = 130 ;
251
255
const NL80211_ATTR_ROAM_SUPPORT : u16 = 131 ;
252
- // const NL80211_ATTR_SCHED_SCAN_MATCH:u16 = 132;
256
+ const NL80211_ATTR_SCHED_SCAN_MATCH : u16 = 132 ;
253
257
const NL80211_ATTR_MAX_MATCH_SETS : u16 = 133 ;
254
258
// const NL80211_ATTR_PMKSA_CANDIDATE:u16 = 134;
255
259
// const NL80211_ATTR_TX_NO_CCK_RATE:u16 = 135;
@@ -275,7 +279,7 @@ const NL80211_ATTR_WDEV: u16 = 153;
275
279
// const NL80211_ATTR_CONN_FAILED_REASON:u16 = 155;
276
280
// const NL80211_ATTR_AUTH_DATA:u16 = 156;
277
281
const NL80211_ATTR_VHT_CAPABILITY : u16 = 157 ;
278
- // const NL80211_ATTR_SCAN_FLAGS:u16 = 158;
282
+ const NL80211_ATTR_SCAN_FLAGS : u16 = 158 ;
279
283
const NL80211_ATTR_CHANNEL_WIDTH : u16 = 159 ;
280
284
const NL80211_ATTR_CENTER_FREQ1 : u16 = 160 ;
281
285
const NL80211_ATTR_CENTER_FREQ2 : u16 = 161 ;
@@ -332,17 +336,17 @@ const NL80211_ATTR_MAX_CSA_COUNTERS: u16 = 206;
332
336
// const NL80211_ATTR_ADMITTED_TIME:u16 = 212;
333
337
// const NL80211_ATTR_SMPS_MODE:u16 = 213;
334
338
// const NL80211_ATTR_OPER_CLASS:u16 = 214;
335
- // const NL80211_ATTR_MAC_MASK:u16 = 215;
339
+ const NL80211_ATTR_MAC_MASK : u16 = 215 ;
336
340
const NL80211_ATTR_WIPHY_SELF_MANAGED_REG : u16 = 216 ;
337
341
const NL80211_ATTR_EXT_FEATURES : u16 = 217 ;
338
342
// const NL80211_ATTR_SURVEY_RADIO_STATS:u16 = 218;
339
343
// const NL80211_ATTR_NETNS_FD:u16 = 219;
340
- // const NL80211_ATTR_SCHED_SCAN_DELAY:u16 = 220;
344
+ const NL80211_ATTR_SCHED_SCAN_DELAY : u16 = 220 ;
341
345
// const NL80211_ATTR_REG_INDOOR:u16 = 221;
342
346
const NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS : u16 = 222 ;
343
347
const NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL : u16 = 223 ;
344
348
const NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS : u16 = 224 ;
345
- // const NL80211_ATTR_SCHED_SCAN_PLANS:u16 = 225;
349
+ const NL80211_ATTR_SCHED_SCAN_PLANS : u16 = 225 ;
346
350
// const NL80211_ATTR_PBSS:u16 = 226;
347
351
// const NL80211_ATTR_BSS_SELECT:u16 = 227;
348
352
// const NL80211_ATTR_STA_SUPPORT_P2P_PS:u16 = 228;
@@ -352,7 +356,7 @@ const NL80211_ATTR_IFTYPE_EXT_CAPA: u16 = 230;
352
356
// const NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR:u16 = 232;
353
357
// const NL80211_ATTR_SCAN_START_TIME_TSF:u16 = 233;
354
358
// const NL80211_ATTR_SCAN_START_TIME_TSF_BSSID:u16 = 234;
355
- // const NL80211_ATTR_MEASUREMENT_DURATION:u16 = 235;
359
+ const NL80211_ATTR_MEASUREMENT_DURATION : u16 = 235 ;
356
360
// const NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY:u16 = 236;
357
361
// const NL80211_ATTR_MESH_PEER_AID:u16 = 237;
358
362
// const NL80211_ATTR_NAN_MASTER_PREF:u16 = 238;
@@ -452,8 +456,6 @@ const NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS: u16 = 323;
452
456
// const NL80211_ATTR_WIPHY_RADIOS:u16 = 331;
453
457
// const NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS:u16 = 332;
454
458
455
- const ETH_ALEN : usize = 6 ;
456
-
457
459
#[ derive( Debug , PartialEq , Eq , Clone ) ]
458
460
#[ non_exhaustive]
459
461
pub enum Nl80211Attr {
@@ -464,6 +466,7 @@ pub enum Nl80211Attr {
464
466
IfType ( Nl80211InterfaceType ) ,
465
467
IfTypeExtCap ( Vec < Nl80211IfTypeExtCapa > ) ,
466
468
Mac ( [ u8 ; ETH_ALEN ] ) ,
469
+ MacMask ( [ u8 ; ETH_ALEN ] ) ,
467
470
MacAddrs ( Vec < [ u8 ; ETH_ALEN ] > ) ,
468
471
Wdev ( u64 ) ,
469
472
Generation ( u32 ) ,
@@ -546,6 +549,33 @@ pub enum Nl80211Attr {
546
549
MaxHwTimestampPeers ( u16 ) ,
547
550
/// Basic Service Set (BSS)
548
551
Bss ( Vec < Nl80211BssInfo > ) ,
552
+ ScanSsids ( Vec < String > ) ,
553
+ ScanFlags ( Nl80211ScanFlags ) ,
554
+ MeasurementDuration ( u16 ) ,
555
+ /// Scan interval in millisecond(ms)
556
+ SchedScanInterval ( u32 ) ,
557
+ /// Delay before the first cycle of a scheduled scan is started. Or the
558
+ /// delay before a WoWLAN net-detect scan is started, counting from the
559
+ /// moment the system is suspended. This value is in seconds.
560
+ SchedScanDelay ( u32 ) ,
561
+ /// Scan frequencies in MHz.
562
+ ScanFrequencies ( Vec < u32 > ) ,
563
+ /// Sets of attributes to match during scheduled scans. Only BSSs
564
+ /// that match any of the sets will be reported. These are pass-thru
565
+ /// filter rules. For a match to succeed, the BSS must match all
566
+ /// attributes of a set. Since not every hardware supports matching all
567
+ /// types of attributes, there is no guarantee that the reported BSSs are
568
+ /// fully complying with the match sets and userspace needs to be able to
569
+ /// ignore them by itself. Thus, the implementation is somewhat
570
+ /// hardware-dependent, but this is only an optimization and the userspace
571
+ /// application needs to handle all the non-filtered results anyway.
572
+ SchedScanMatch ( Vec < Nl80211SchedScanMatch > ) ,
573
+ /// A list of scan plans for scheduled scan. Each scan plan defines the
574
+ /// number of scan iterations and the interval between scans. The last scan
575
+ /// plan will always run infinitely, thus it must not specify the number of
576
+ /// iterations, only the interval between scans. The scan plans are
577
+ /// executed sequentially.
578
+ SchedScanPlans ( Vec < Nl80211SchedScanPlan > ) ,
549
579
Other ( DefaultNla ) ,
550
580
}
551
581
@@ -576,10 +606,12 @@ impl Nla for Nl80211Attr {
576
606
| Self :: SchedScanMaxReqs ( _)
577
607
| Self :: TransmitQueueLimit ( _)
578
608
| Self :: TransmitQueueMemoryLimit ( _)
579
- | Self :: TransmitQueueQuantum ( _) => 4 ,
609
+ | Self :: TransmitQueueQuantum ( _)
610
+ | Self :: SchedScanInterval ( _)
611
+ | Self :: SchedScanDelay ( _) => 4 ,
580
612
Self :: Wdev ( _) => 8 ,
581
613
Self :: IfName ( s) | Self :: Ssid ( s) | Self :: WiphyName ( s) => s. len ( ) + 1 ,
582
- Self :: Mac ( _) => ETH_ALEN ,
614
+ Self :: Mac ( _) | Self :: MacMask ( _ ) => ETH_ALEN ,
583
615
Self :: MacAddrs ( s) => {
584
616
MacAddressNlas :: from ( s) . as_slice ( ) . buffer_len ( )
585
617
}
@@ -633,9 +665,19 @@ impl Nla for Nl80211Attr {
633
665
Self :: EmlCapability ( _)
634
666
| Self :: MldCapaAndOps ( _)
635
667
| Self :: MaxNumAkmSuites ( _)
636
- | Self :: MaxHwTimestampPeers ( _) => 2 ,
668
+ | Self :: MaxHwTimestampPeers ( _)
669
+ | Self :: MeasurementDuration ( _) => 2 ,
637
670
Self :: Bands ( _) => Nl80211BandTypes :: LENGTH ,
638
671
Self :: Bss ( v) => v. as_slice ( ) . buffer_len ( ) ,
672
+ Self :: ScanSsids ( v) => {
673
+ Nla80211ScanSsidNlas :: from ( v) . as_slice ( ) . buffer_len ( )
674
+ }
675
+ Self :: ScanFlags ( v) => v. buffer_len ( ) ,
676
+ Self :: ScanFrequencies ( v) => {
677
+ Nla80211ScanFreqNlas :: from ( v) . as_slice ( ) . buffer_len ( )
678
+ }
679
+ Self :: SchedScanMatch ( v) => v. as_slice ( ) . buffer_len ( ) ,
680
+ Self :: SchedScanPlans ( v) => v. as_slice ( ) . buffer_len ( ) ,
639
681
Self :: Other ( attr) => attr. value_len ( ) ,
640
682
}
641
683
}
@@ -648,6 +690,7 @@ impl Nla for Nl80211Attr {
648
690
Self :: IfName ( _) => NL80211_ATTR_IFNAME ,
649
691
Self :: IfType ( _) => NL80211_ATTR_IFTYPE ,
650
692
Self :: Mac ( _) => NL80211_ATTR_MAC ,
693
+ Self :: MacMask ( _) => NL80211_ATTR_MAC_MASK ,
651
694
Self :: MacAddrs ( _) => NL80211_ATTR_MAC_ADDRS ,
652
695
Self :: Wdev ( _) => NL80211_ATTR_WDEV ,
653
696
Self :: Generation ( _) => NL80211_ATTR_GENERATION ,
@@ -733,6 +776,14 @@ impl Nla for Nl80211Attr {
733
776
Self :: MaxNumAkmSuites ( _) => NL80211_ATTR_MAX_NUM_AKM_SUITES ,
734
777
Self :: MaxHwTimestampPeers ( _) => NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS ,
735
778
Self :: Bss ( _) => NL80211_ATTR_BSS ,
779
+ Self :: ScanSsids ( _) => NL80211_ATTR_SCAN_SSIDS ,
780
+ Self :: ScanFlags ( _) => NL80211_ATTR_SCAN_FLAGS ,
781
+ Self :: MeasurementDuration ( _) => NL80211_ATTR_MEASUREMENT_DURATION ,
782
+ Self :: SchedScanInterval ( _) => NL80211_ATTR_SCHED_SCAN_INTERVAL ,
783
+ Self :: SchedScanDelay ( _) => NL80211_ATTR_SCHED_SCAN_DELAY ,
784
+ Self :: ScanFrequencies ( _) => NL80211_ATTR_SCAN_FREQUENCIES ,
785
+ Self :: SchedScanMatch ( _) => NL80211_ATTR_SCHED_SCAN_MATCH ,
786
+ Self :: SchedScanPlans ( _) => NL80211_ATTR_SCHED_SCAN_PLANS ,
736
787
Self :: Other ( attr) => attr. kind ( ) ,
737
788
}
738
789
}
@@ -760,13 +811,15 @@ impl Nla for Nl80211Attr {
760
811
| Self :: SchedScanMaxReqs ( d)
761
812
| Self :: TransmitQueueLimit ( d)
762
813
| Self :: TransmitQueueMemoryLimit ( d)
763
- | Self :: TransmitQueueQuantum ( d) => write_u32 ( buffer, * d) ,
814
+ | Self :: TransmitQueueQuantum ( d)
815
+ | Self :: SchedScanInterval ( d)
816
+ | Self :: SchedScanDelay ( d) => write_u32 ( buffer, * d) ,
764
817
Self :: MaxScanIeLen ( d) | Self :: MaxSchedScanIeLen ( d) => {
765
818
write_u16 ( buffer, * d)
766
819
}
767
820
Self :: Wdev ( d) => write_u64 ( buffer, * d) ,
768
821
Self :: IfType ( d) => write_u32 ( buffer, ( * d) . into ( ) ) ,
769
- Self :: Mac ( s) => buffer. copy_from_slice ( s) ,
822
+ Self :: Mac ( s) | Self :: MacMask ( s ) => buffer. copy_from_slice ( s) ,
770
823
Self :: MacAddrs ( s) => {
771
824
MacAddressNlas :: from ( s) . as_slice ( ) . emit ( buffer)
772
825
}
@@ -834,9 +887,19 @@ impl Nla for Nl80211Attr {
834
887
Self :: EmlCapability ( d)
835
888
| Self :: MldCapaAndOps ( d)
836
889
| Self :: MaxNumAkmSuites ( d)
837
- | Self :: MaxHwTimestampPeers ( d) => write_u16 ( buffer, * d) ,
890
+ | Self :: MaxHwTimestampPeers ( d)
891
+ | Self :: MeasurementDuration ( d) => write_u16 ( buffer, * d) ,
838
892
Self :: Bands ( v) => v. emit ( buffer) ,
839
893
Self :: Bss ( v) => v. as_slice ( ) . emit ( buffer) ,
894
+ Self :: ScanSsids ( v) => {
895
+ Nla80211ScanSsidNlas :: from ( v) . as_slice ( ) . emit ( buffer)
896
+ }
897
+ Self :: ScanFlags ( v) => v. emit ( buffer) ,
898
+ Self :: ScanFrequencies ( v) => {
899
+ Nla80211ScanFreqNlas :: from ( v) . as_slice ( ) . emit ( buffer)
900
+ }
901
+ Self :: SchedScanMatch ( v) => v. as_slice ( ) . emit ( buffer) ,
902
+ Self :: SchedScanPlans ( v) => v. as_slice ( ) . emit ( buffer) ,
840
903
Self :: Other ( attr) => attr. emit ( buffer) ,
841
904
}
842
905
}
@@ -882,11 +945,26 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Nl80211Attr {
882
945
ret
883
946
} else {
884
947
return Err ( format ! (
885
- "Invalid length of NL80211_ATTR_MAC, expected length {} got {:?}" ,
948
+ "Invalid length of NL80211_ATTR_MAC, \
949
+ expected length {} got {:?}",
886
950
ETH_ALEN , payload
887
951
)
888
952
. into ( ) ) ;
889
953
} ) ,
954
+ NL80211_ATTR_MAC_MASK => {
955
+ Self :: MacMask ( if payload. len ( ) == ETH_ALEN {
956
+ let mut ret = [ 0u8 ; ETH_ALEN ] ;
957
+ ret. copy_from_slice ( & payload[ ..ETH_ALEN ] ) ;
958
+ ret
959
+ } else {
960
+ return Err ( format ! (
961
+ "Invalid length of NL80211_ATTR_MAC_MASK, \
962
+ expected length {} got {:?}",
963
+ ETH_ALEN , payload
964
+ )
965
+ . into ( ) ) ;
966
+ } )
967
+ }
890
968
NL80211_ATTR_MAC_ADDRS => {
891
969
Self :: MacAddrs ( MacAddressNlas :: parse ( payload) ?. into ( ) )
892
970
}
@@ -1347,6 +1425,60 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Nl80211Attr {
1347
1425
payload
1348
1426
) ) ?,
1349
1427
) ,
1428
+ NL80211_ATTR_SCAN_SSIDS => {
1429
+ Self :: ScanSsids ( Nla80211ScanSsidNlas :: parse ( payload) ?. into ( ) )
1430
+ }
1431
+ NL80211_ATTR_SCAN_FLAGS => {
1432
+ Self :: ScanFlags ( Nl80211ScanFlags :: parse ( payload) ?)
1433
+ }
1434
+ NL80211_ATTR_MEASUREMENT_DURATION => {
1435
+ let err_msg = format ! (
1436
+ "Invalid NL80211_ATTR_MEASUREMENT_DURATION value {:?}" ,
1437
+ payload
1438
+ ) ;
1439
+ Self :: MeasurementDuration ( parse_u16 ( payload) . context ( err_msg) ?)
1440
+ }
1441
+ NL80211_ATTR_SCHED_SCAN_INTERVAL => {
1442
+ let err_msg = format ! (
1443
+ "Invalid NL80211_ATTR_SCHED_SCAN_INTERVAL value {:?}" ,
1444
+ payload
1445
+ ) ;
1446
+ Self :: SchedScanInterval ( parse_u32 ( payload) . context ( err_msg) ?)
1447
+ }
1448
+ NL80211_ATTR_SCHED_SCAN_DELAY => {
1449
+ let err_msg = format ! (
1450
+ "Invalid NL80211_ATTR_SCHED_SCAN_DELAY value {:?}" ,
1451
+ payload
1452
+ ) ;
1453
+ Self :: SchedScanDelay ( parse_u32 ( payload) . context ( err_msg) ?)
1454
+ }
1455
+ NL80211_ATTR_SCAN_FREQUENCIES => Self :: ScanFrequencies (
1456
+ Nla80211ScanFreqNlas :: parse ( payload) ?. into ( ) ,
1457
+ ) ,
1458
+ NL80211_ATTR_SCHED_SCAN_MATCH => {
1459
+ let err_msg = format ! (
1460
+ "Invalid NL80211_ATTR_SCHED_SCAN_MATCH value {:?}" ,
1461
+ payload
1462
+ ) ;
1463
+ let mut nlas = Vec :: new ( ) ;
1464
+ for nla in NlasIterator :: new ( payload) {
1465
+ let nla = & nla. context ( err_msg. clone ( ) ) ?;
1466
+ nlas. push ( Nl80211SchedScanMatch :: parse ( nla) ?) ;
1467
+ }
1468
+ Self :: SchedScanMatch ( nlas)
1469
+ }
1470
+ NL80211_ATTR_SCHED_SCAN_PLANS => {
1471
+ let err_msg = format ! (
1472
+ "Invalid NL80211_ATTR_SCHED_SCAN_PLANS value {:?}" ,
1473
+ payload
1474
+ ) ;
1475
+ let mut nlas = Vec :: new ( ) ;
1476
+ for nla in NlasIterator :: new ( payload) {
1477
+ let nla = & nla. context ( err_msg. clone ( ) ) ?;
1478
+ nlas. push ( Nl80211SchedScanPlan :: parse ( nla) ?) ;
1479
+ }
1480
+ Self :: SchedScanPlans ( nlas)
1481
+ }
1350
1482
_ => Self :: Other (
1351
1483
DefaultNla :: parse ( buf) . context ( "invalid NLA (unknown kind)" ) ?,
1352
1484
) ,
0 commit comments