1use super::{Header, IeSummaryIter, IeType};
6use anyhow::format_err;
7use std::collections::BTreeMap;
8use std::mem::size_of;
9use std::ops::Range;
10
11const IES_MERGER_BUFFER_LIMIT: usize = 10000;
12
13#[derive(Debug)]
27pub struct IesMerger {
28 ies_updater: IesUpdater,
29 buffer_overflow: bool,
30 merge_ie_failures: usize,
31}
32
33impl IesMerger {
34 pub fn new(ies: Vec<u8>) -> Self {
35 Self { ies_updater: IesUpdater::new(ies), buffer_overflow: false, merge_ie_failures: 0 }
36 }
37
38 pub fn merge(&mut self, ies: &[u8]) {
39 for (ie_type, range) in IeSummaryIter::new(ies) {
40 let add_new = match self.ies_updater.get(&ie_type) {
41 Some(old) => should_add_new(ie_type, old, &ies[range.clone()]),
42 None => true,
43 };
44 let new_addition_len = range.end - range.start;
45 if add_new {
48 if self.ies_updater.buf_len() + new_addition_len <= IES_MERGER_BUFFER_LIMIT {
49 if let Err(_e) = self.ies_updater.set(ie_type, &ies[range]) {
52 self.merge_ie_failures += 1;
53 }
54 } else {
55 self.buffer_overflow = true;
56 }
57 }
58 }
59 }
60
61 pub fn finalize(&mut self) -> Vec<u8> {
63 self.ies_updater.finalize()
64 }
65
66 pub fn buffer_overflow(&mut self) -> bool {
69 self.buffer_overflow
70 }
71
72 pub fn merge_ie_failures(&self) -> usize {
75 self.merge_ie_failures
76 }
77}
78
79#[derive(Debug)]
80pub struct IesUpdater {
81 ies_summaries: BTreeMap<IeType, Range<usize>>,
84 ies_buf: Vec<u8>,
85}
86
87impl IesUpdater {
88 pub fn new(ies: Vec<u8>) -> Self {
89 let mut ies_summaries = BTreeMap::new();
90 for (ie_type, range) in IeSummaryIter::new(&ies[..]) {
91 ies_summaries.insert(ie_type, range);
92 }
93 Self { ies_summaries, ies_buf: ies }
94 }
95
96 pub fn remove(&mut self, ie_type: &IeType) {
98 self.ies_summaries.remove(ie_type);
99 }
100
101 pub fn set(&mut self, ie_type: IeType, ie_content: &[u8]) -> Result<(), anyhow::Error> {
104 if ie_type.extra_len() + ie_content.len() > std::u8::MAX.into() {
107 return Err(format_err!("ie_content too large"));
108 }
109
110 let start_idx = self.ies_buf.len();
111 self.ies_buf.extend_from_slice(ie_content);
112 self.ies_summaries.insert(ie_type, start_idx..self.ies_buf.len());
113 Ok(())
114 }
115
116 pub fn set_raw(&mut self, ie: &[u8]) -> Result<(), anyhow::Error> {
120 if ie.is_empty() {
121 return Ok(());
122 }
123 match IeSummaryIter::new(&ie[..]).next() {
124 Some((ie_type, range)) => self.set(ie_type, &ie[range]),
125 None => Err(format_err!("failed parsing `ie`")),
126 }
127 }
128
129 pub fn get(&self, ie_type: &IeType) -> Option<&[u8]> {
131 self.ies_summaries.get(ie_type).map(|range| &self.ies_buf[range.clone()])
132 }
133
134 fn buf_len(&self) -> usize {
135 self.ies_buf.len()
136 }
137
138 pub fn finalize(&mut self) -> Vec<u8> {
140 let total_len = self
141 .ies_summaries
142 .iter()
143 .map(|(ie_type, r)| size_of::<Header>() + ie_type.extra_len() + (r.end - r.start))
144 .sum();
145 let mut ies = Vec::with_capacity(total_len);
146 for (ie_type, range) in self.ies_summaries.iter() {
147 let id = ie_type.basic_id().0;
148 let len = ie_type.extra_len() + (range.end - range.start);
149 ies.extend_from_slice(&[id, len as u8]);
151 ies.extend_from_slice(ie_type.extra_bytes());
152 ies.extend_from_slice(&self.ies_buf[range.clone()]);
153 }
154 ies
155 }
156}
157
158fn should_add_new(ie_type: IeType, old: &[u8], new: &[u8]) -> bool {
159 if old == new {
161 return false;
162 }
163
164 if ie_type == IeType::SSID {
166 if new.len() < size_of::<Header>() {
167 return false;
168 }
169 let ssid = &new[2..];
170 if ssid.iter().all(|c| *c == 0u8) {
171 return false;
172 }
173 }
174
175 new.len() >= old.len()
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 #[rustfmt::skip]
192 const BEACON_FRAME_IES: &'static [u8] = &[
193 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x2d, 0x73, 0x73, 0x69, 0x64,
195 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c,
197 0x03, 0x01, 0x9d,
199 0x05, 0x04, 0x00, 0x01, 0x00, 0x00,
201 0x20, 0x01, 0x03,
203 0x2d, 0x1a,
205 0xef, 0x09, 0x1b, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x14, 0x01, 0x00,
213 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00, 0x3d, 0x16,
219 0x9d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x0e, 0x14, 0x00, 0x0a, 0x00, 0x2c, 0x01, 0xc8, 0x00, 0x14, 0x00, 0x05, 0x00, 0x19, 0x00,
225 0x7f, 0x08, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x40,
227 0xbf, 0x0c,
229 0xb2, 0x01, 0x80, 0x33, 0xea, 0xff, 0x00, 0x00, 0xea, 0xff, 0x00, 0x00, 0xc0, 0x05, 0x01, 0x9b, 0x00, 0xfc, 0xff,
233 0xc3, 0x04, 0x02, 0xc4, 0xc4, 0xc4,
235 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f,
237 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01,
239 0x80, 0x00,
241 0x03, 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00, 0xdd, 0x1d, 0x00, 0x50, 0xf2, 0x04, 0x10, 0x4a, 0x00, 0x01, 0x10, 0x10, 0x44, 0x00, 0x01,
247 0x02, 0x10, 0x3c, 0x00, 0x01, 0x03, 0x10, 0x49, 0x00, 0x06, 0x00, 0x37, 0x2a, 0x00, 0x01,
248 0x20,
249 ];
250
251 #[rustfmt::skip]
252 const PROBE_RESP_IES: &'static [u8] = &[
253 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x2d, 0x73, 0x73, 0x69, 0x64,
255 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c,
257 0x03, 0x01, 0x9d,
259 0x20, 0x01, 0x03,
261 0x2d, 0x1a,
263 0xef, 0x09, 0x1b, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x14, 0x01, 0x00,
271 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00, 0x3d, 0x16,
277 0x9d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x0e, 0x14, 0x00, 0x0a, 0x00, 0x2c, 0x01, 0xc8, 0x00, 0x14, 0x00, 0x05, 0x00, 0x19, 0x00,
283 0x7f, 0x08, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x40,
285 0xbf, 0x0c,
287 0xb2, 0x01, 0x80, 0x33, 0xea, 0xff, 0x00, 0x00, 0xea, 0xff, 0x00, 0x00, 0xc0, 0x05, 0x01, 0x9b, 0x00, 0xfc, 0xff,
291 0xc3, 0x04, 0x02, 0xc4, 0xc4, 0xc4,
293 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f,
295 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01,
297 0x80, 0x00,
299 0x03, 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00, 0xdd, 0x85, 0x00, 0x50, 0xf2, 0x04, 0x10, 0x4a, 0x00, 0x01, 0x10, 0x10, 0x44, 0x00, 0x01,
305 0x02, 0x10, 0x3b, 0x00, 0x01, 0x03, 0x10, 0x47, 0x00, 0x10, 0x87, 0x65, 0x43, 0x21, 0x9a,
306 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x98, 0xda, 0xc4, 0x8e, 0x86, 0xc8, 0x10, 0x21, 0x00, 0x07,
307 0x54, 0x50, 0x2d, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x23, 0x00, 0x09, 0x41, 0x72, 0x63, 0x68,
308 0x65, 0x72, 0x20, 0x41, 0x37, 0x10, 0x24, 0x00, 0x03, 0x31, 0x2e, 0x30, 0x10, 0x42, 0x00,
309 0x0c, 0x41, 0x72, 0x63, 0x68, 0x65, 0x72, 0x20, 0x41, 0x37, 0x20, 0x76, 0x35, 0x10, 0x54,
310 0x00, 0x08, 0x00, 0x06, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01, 0x10, 0x11, 0x00, 0x0a, 0x41,
311 0x72, 0x63, 0x68, 0x65, 0x72, 0x41, 0x37, 0x76, 0x35, 0x10, 0x08, 0x00, 0x02, 0x00, 0x04,
312 0x10, 0x3c, 0x00, 0x01, 0x03, 0x10, 0x49, 0x00, 0x06, 0x00, 0x37, 0x2a, 0x00, 0x01, 0x20,
313 ];
314
315 #[rustfmt::skip]
316 const MERGED_IES: &'static [u8] = &[
317 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x2d, 0x73, 0x73, 0x69, 0x64,
319 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c,
321 0x03, 0x01, 0x9d,
323 0x05, 0x04, 0x00, 0x01, 0x00, 0x00,
325 0x20, 0x01, 0x03,
327 0x2d, 0x1a,
329 0xef, 0x09, 0x1b, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x14, 0x01, 0x00,
337 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00, 0x3d, 0x16,
343 0x9d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x0e, 0x14, 0x00, 0x0a, 0x00, 0x2c, 0x01, 0xc8, 0x00, 0x14, 0x00, 0x05, 0x00, 0x19, 0x00,
349 0x7f, 0x08, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x40,
351 0xbf, 0x0c,
353 0xb2, 0x01, 0x80, 0x33, 0xea, 0xff, 0x00, 0x00, 0xea, 0xff, 0x00, 0x00, 0xc0, 0x05, 0x01, 0x9b, 0x00, 0xfc, 0xff,
357 0xc3, 0x04, 0x02, 0xc4, 0xc4, 0xc4,
359 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f,
361 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01,
363 0x80, 0x00,
365 0x03, 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00, 0xdd, 0x85, 0x00, 0x50, 0xf2, 0x04, 0x10, 0x4a, 0x00, 0x01, 0x10, 0x10, 0x44, 0x00, 0x01,
371 0x02, 0x10, 0x3b, 0x00, 0x01, 0x03, 0x10, 0x47, 0x00, 0x10, 0x87, 0x65, 0x43, 0x21, 0x9a,
372 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x98, 0xda, 0xc4, 0x8e, 0x86, 0xc8, 0x10, 0x21, 0x00, 0x07,
373 0x54, 0x50, 0x2d, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x23, 0x00, 0x09, 0x41, 0x72, 0x63, 0x68,
374 0x65, 0x72, 0x20, 0x41, 0x37, 0x10, 0x24, 0x00, 0x03, 0x31, 0x2e, 0x30, 0x10, 0x42, 0x00,
375 0x0c, 0x41, 0x72, 0x63, 0x68, 0x65, 0x72, 0x20, 0x41, 0x37, 0x20, 0x76, 0x35, 0x10, 0x54,
376 0x00, 0x08, 0x00, 0x06, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01, 0x10, 0x11, 0x00, 0x0a, 0x41,
377 0x72, 0x63, 0x68, 0x65, 0x72, 0x41, 0x37, 0x76, 0x35, 0x10, 0x08, 0x00, 0x02, 0x00, 0x04,
378 0x10, 0x3c, 0x00, 0x01, 0x03, 0x10, 0x49, 0x00, 0x06, 0x00, 0x37, 0x2a, 0x00, 0x01, 0x20,
379 ];
380
381 #[test]
382 fn test_no_merge() {
383 let ies = IesMerger::new(BEACON_FRAME_IES.to_vec()).finalize();
384 assert_eq!(&ies[..], BEACON_FRAME_IES);
385 }
386
387 #[test]
388 fn test_merge_same_ies() {
389 let mut ies_merger = IesMerger::new(BEACON_FRAME_IES.to_vec());
390 ies_merger.merge(BEACON_FRAME_IES);
391 let ies = ies_merger.finalize();
392 assert_eq!(&ies[..], BEACON_FRAME_IES);
393 assert!(!ies_merger.buffer_overflow());
394 }
395
396 #[test]
397 fn test_merge_different_ies() {
398 let mut ies_merger = IesMerger::new(BEACON_FRAME_IES.to_vec());
399 ies_merger.merge(PROBE_RESP_IES);
400 let ies = ies_merger.finalize();
401 assert_eq!(&ies[..], MERGED_IES);
402 assert!(!ies_merger.buffer_overflow());
403 }
404
405 #[test]
408 fn test_merge_different_ies_commutative() {
409 let mut ies_merger1 = IesMerger::new(BEACON_FRAME_IES.to_vec());
410 ies_merger1.merge(PROBE_RESP_IES);
411 let ies1 = ies_merger1.finalize();
412
413 let mut ies_merger2 = IesMerger::new(PROBE_RESP_IES.to_vec());
414 ies_merger2.merge(BEACON_FRAME_IES);
415 let ies2 = ies_merger2.finalize();
416
417 assert_eq!(ies1, ies2);
418 }
419
420 #[test]
423 fn test_merge_redundant() {
424 let mut ies_merger = IesMerger::new(BEACON_FRAME_IES.to_vec());
425 ies_merger.merge(BEACON_FRAME_IES);
426 ies_merger.merge(PROBE_RESP_IES);
427 ies_merger.merge(PROBE_RESP_IES);
428 ies_merger.merge(BEACON_FRAME_IES);
429 let ies = ies_merger.finalize();
430
431 assert_eq!(&ies[..], MERGED_IES);
432 }
433
434 #[test]
436 fn test_merge_is_resilient() {
437 const LEN: u8 = 255;
438 let mut ies = vec![0xdd, LEN];
439 ies.extend(vec![0xff; LEN as usize].iter());
440
441 let mut ies_merger = IesMerger::new(ies.clone());
442 for i in 0..255 {
443 let last_idx = ies.len() - 1;
444 ies[last_idx] = i; ies_merger.merge(&ies[..]);
446 }
447 assert!(ies_merger.ies_updater.buf_len() <= IES_MERGER_BUFFER_LIMIT);
449 assert!(ies_merger.buffer_overflow());
451
452 let result_ies = ies_merger.finalize();
454 assert_eq!(ies.len(), result_ies.len());
455 assert_eq!(ies[..ies.len() - 1], result_ies[..result_ies.len() - 1]);
457 }
458
459 #[test]
460 fn test_merge_prioritize_non_hidden_ssid_1() {
461 let hidden_ssid_ie = vec![0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
462 let mut ies_merger = IesMerger::new(BEACON_FRAME_IES.to_vec());
463 ies_merger.merge(&hidden_ssid_ie[..]);
464 let ies = ies_merger.finalize();
465
466 assert_eq!(&ies[..], BEACON_FRAME_IES);
468
469 let mut ies_merger = IesMerger::new(hidden_ssid_ie.clone());
471 assert_eq!(ies_merger.finalize(), hidden_ssid_ie);
473
474 let mut ies_merger = IesMerger::new(hidden_ssid_ie);
475 ies_merger.merge(BEACON_FRAME_IES);
476 let ies = ies_merger.finalize();
477
478 assert_eq!(&ies[..], BEACON_FRAME_IES);
480 }
481
482 #[test]
483 fn test_ie_updater_get() {
484 let ies = vec![
485 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
489 let ies_updater = IesUpdater::new(ies);
490
491 assert_eq!(ies_updater.get(&IeType::SSID), Some(&[10, 20][..]));
492 assert_eq!(
493 ies_updater.get(&IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00])),
494 Some(&[0x00, 0xff, 0x7f][..])
495 );
496 assert_eq!(ies_updater.get(&IeType::new_extended(5)), Some(&[1][..]));
497
498 assert_eq!(ies_updater.get(&IeType::SUPPORTED_RATES), None);
499 assert_eq!(
500 ies_updater.get(&IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x01])),
501 None
502 );
503 assert_eq!(ies_updater.get(&IeType::new_extended(6)), None);
504 }
505
506 #[test]
507 fn test_ie_updater_set_replace() {
508 let ies = vec![
509 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
513 let mut ies_updater = IesUpdater::new(ies);
514
515 ies_updater.set(IeType::SSID, &[30, 40, 50]).expect("set basic succeeds");
516 ies_updater
517 .set(IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00]), &[1, 3, 3, 7])
518 .expect("set vendor succeeds");
519 ies_updater.set(IeType::new_extended(5), &[4, 2]).expect("set extended succeeds");
520
521 assert_eq!(ies_updater.get(&IeType::SSID), Some(&[30, 40, 50][..]));
522 assert_eq!(
523 ies_updater.get(&IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00])),
524 Some(&[1, 3, 3, 7][..])
525 );
526 assert_eq!(ies_updater.get(&IeType::new_extended(5)), Some(&[4, 2][..]));
527
528 assert_eq!(
529 &ies_updater.finalize()[..],
530 &[
531 0, 3, 30, 40, 50, 0xdd, 0x0a, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 1, 3, 3, 7, 255, 3, 5, 4, 2, ]
535 );
536 }
537
538 #[test]
539 fn test_ie_updater_set_new() {
540 let ies = vec![
541 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
545 let mut ies_updater = IesUpdater::new(ies);
546
547 ies_updater.set(IeType::SUPPORTED_RATES, &[30, 40, 50]).expect("set basic succeeds");
548 ies_updater
549 .set(IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x01]), &[1, 3, 3, 7])
550 .expect("set vendor succeeds");
551 ies_updater.set(IeType::new_extended(6), &[4, 2]).expect("set extended succeeds");
552
553 assert_eq!(ies_updater.get(&IeType::SUPPORTED_RATES), Some(&[30, 40, 50][..]));
554 assert_eq!(
555 ies_updater.get(&IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x01])),
556 Some(&[1, 3, 3, 7][..])
557 );
558 assert_eq!(ies_updater.get(&IeType::new_extended(6)), Some(&[4, 2][..]));
559
560 assert_eq!(
561 &ies_updater.finalize()[..],
562 &[
563 0, 2, 10, 20, 1, 3, 30, 40, 50, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 0xdd, 0x0a, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x01, 1, 3, 3, 7, 255, 2, 5, 1, 255, 3, 6, 4, 2, ]
570 )
571 }
572
573 #[test]
574 fn test_ie_updater_set_ie_too_large() {
575 let ies = vec![
576 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
580 let mut ies_updater = IesUpdater::new(ies);
581 ies_updater.set(IeType::SSID, &[11; 256]).expect_err("set basic fails");
582 ies_updater
583 .set(IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00]), &[11; 250])
584 .expect_err("set vendor fails");
585 ies_updater.set(IeType::new_extended(5), &[11; 255]).expect_err("set extended fails");
586
587 assert_eq!(
589 &ies_updater.finalize()[..],
590 &[
591 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ]
595 );
596 }
597
598 #[test]
599 fn test_ie_updater_set_raw_ie() {
600 let ies = vec![];
601
602 let mut ies_updater = IesUpdater::new(ies.clone());
603 ies_updater.set_raw(&[0, 2, 10, 20]).expect("set right length succeeds");
604 ies_updater.set_raw(&[1, 2, 70]).expect_err("set buffer too small fails");
605 ies_updater.set_raw(&[]).expect("set empty doesn't return error");
606 ies_updater.set_raw(&[2, 2, 30, 40, 50, 60]).expect("set truncated succeeds");
607
608 assert_eq!(&ies_updater.finalize()[..], &[0, 2, 10, 20, 2, 2, 30, 40])
609 }
610
611 #[test]
612 fn test_ie_updater_remove() {
613 let ies = vec![
614 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
618
619 let mut ies_updater = IesUpdater::new(ies.clone());
620 ies_updater.remove(&IeType::SSID);
621 assert_eq!(ies_updater.get(&IeType::SSID), None);
622 assert_eq!(
623 ies_updater.finalize(),
624 &[
625 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ]
628 );
629
630 let mut ies_updater = IesUpdater::new(ies.clone());
631 ies_updater.remove(&IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00]));
632 assert_eq!(
633 ies_updater.get(&IeType::new_vendor([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00])),
634 None
635 );
636 assert_eq!(
637 ies_updater.finalize(),
638 &[
639 0, 2, 10, 20, 255, 2, 5, 1, ],
642 );
643
644 let mut ies_updater = IesUpdater::new(ies);
645 ies_updater.remove(&IeType::new_extended(5));
646 assert_eq!(ies_updater.get(&IeType::new_extended(5)), None);
647 assert_eq!(
648 ies_updater.finalize(),
649 &[
650 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, ],
653 );
654 }
655}