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, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xaa, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
490 let ies_updater = IesUpdater::new(ies);
491
492 assert_eq!(ies_updater.get(&IeType::SSID), Some(&[10, 20][..]));
493 assert_eq!(
494 ies_updater.get(&IeType::new_vendor4([0x50, 0x6f, 0x9a, 0x1c])),
495 Some(&[0xaa][..])
496 );
497 assert_eq!(
498 ies_updater.get(&IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00])),
499 Some(&[0x00, 0xff, 0x7f][..])
500 );
501 assert_eq!(ies_updater.get(&IeType::new_extended(5)), Some(&[1][..]));
502
503 assert_eq!(ies_updater.get(&IeType::SUPPORTED_RATES), None);
504 assert_eq!(ies_updater.get(&IeType::new_vendor4([0x50, 0x6f, 0x9a, 0x1d])), None);
505 assert_eq!(
506 ies_updater.get(&IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x01])),
507 None
508 );
509 assert_eq!(ies_updater.get(&IeType::new_extended(6)), None);
510 }
511
512 #[test]
513 fn test_ie_updater_set_replace() {
514 let ies = vec![
515 0, 2, 10, 20, 0xdd, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xaa, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
520 let mut ies_updater = IesUpdater::new(ies);
521
522 ies_updater.set(IeType::SSID, &[30, 40, 50]).expect("set basic succeeds");
523 ies_updater
524 .set(IeType::new_vendor4([0x50, 0x6f, 0x9a, 0x1c]), &[0xbb])
525 .expect("set vendor succeeds");
526 ies_updater
527 .set(IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00]), &[1, 3, 3, 7])
528 .expect("set vendor succeeds");
529 ies_updater.set(IeType::new_extended(5), &[4, 2]).expect("set extended succeeds");
530
531 assert_eq!(ies_updater.get(&IeType::SSID), Some(&[30, 40, 50][..]));
532 assert_eq!(
533 ies_updater.get(&IeType::new_vendor4([0x50, 0x6f, 0x9a, 0x1c])),
534 Some(&[0xbb][..])
535 );
536 assert_eq!(
537 ies_updater.get(&IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00])),
538 Some(&[1, 3, 3, 7][..])
539 );
540 assert_eq!(ies_updater.get(&IeType::new_extended(5)), Some(&[4, 2][..]));
541
542 assert_eq!(
543 &ies_updater.finalize()[..],
544 &[
545 0, 3, 30, 40, 50, 0xdd, 0x0a, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 1, 3, 3, 7, 0xdd, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xbb, 255, 3, 5, 4, 2, ]
550 );
551 }
552
553 #[test]
554 fn test_ie_updater_set_new() {
555 let ies = vec![
556 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
560 let mut ies_updater = IesUpdater::new(ies);
561
562 ies_updater.set(IeType::SUPPORTED_RATES, &[30, 40, 50]).expect("set basic succeeds");
563 ies_updater
564 .set(IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x01]), &[1, 3, 3, 7])
565 .expect("set vendor succeeds");
566 ies_updater.set(IeType::new_extended(6), &[4, 2]).expect("set extended succeeds");
567
568 assert_eq!(ies_updater.get(&IeType::SUPPORTED_RATES), Some(&[30, 40, 50][..]));
569 assert_eq!(
570 ies_updater.get(&IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x01])),
571 Some(&[1, 3, 3, 7][..])
572 );
573 assert_eq!(ies_updater.get(&IeType::new_extended(6)), Some(&[4, 2][..]));
574
575 assert_eq!(
576 &ies_updater.finalize()[..],
577 &[
578 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, ]
585 )
586 }
587
588 #[test]
589 fn test_ie_updater_set_ie_too_large() {
590 let ies = vec![
591 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
595 let mut ies_updater = IesUpdater::new(ies);
596 ies_updater.set(IeType::SSID, &[11; 256]).expect_err("set basic fails");
597 ies_updater
598 .set(IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00]), &[11; 250])
599 .expect_err("set vendor fails");
600 ies_updater.set(IeType::new_extended(5), &[11; 255]).expect_err("set extended fails");
601
602 assert_eq!(
604 &ies_updater.finalize()[..],
605 &[
606 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ]
610 );
611 }
612
613 #[test]
614 fn test_ie_updater_set_raw_ie() {
615 let ies = vec![];
616
617 let mut ies_updater = IesUpdater::new(ies.clone());
618 ies_updater.set_raw(&[0, 2, 10, 20]).expect("set right length succeeds");
619 ies_updater.set_raw(&[1, 2, 70]).expect_err("set buffer too small fails");
620 ies_updater.set_raw(&[]).expect("set empty doesn't return error");
621 ies_updater.set_raw(&[2, 2, 30, 40, 50, 60]).expect("set truncated succeeds");
622
623 assert_eq!(&ies_updater.finalize()[..], &[0, 2, 10, 20, 2, 2, 30, 40])
624 }
625
626 #[test]
627 fn test_ie_updater_remove() {
628 let ies = vec![
629 0, 2, 10, 20, 0xdd, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xaa, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ];
634
635 let mut ies_updater = IesUpdater::new(ies.clone());
636 ies_updater.remove(&IeType::SSID);
637 assert_eq!(ies_updater.get(&IeType::SSID), None);
638 assert_eq!(
639 ies_updater.finalize(),
640 &[
641 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 0xdd, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xaa, 255, 2, 5, 1, ]
645 );
646
647 let mut ies_updater = IesUpdater::new(ies.clone());
648 ies_updater.remove(&IeType::new_vendor4([0x50, 0x6f, 0x9a, 0x1c]));
649 assert_eq!(ies_updater.get(&IeType::new_vendor4([0x50, 0x6f, 0x9a, 0x1c])), None);
650 assert_eq!(
651 ies_updater.finalize(),
652 &[
653 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 255, 2, 5, 1, ],
657 );
658
659 let mut ies_updater = IesUpdater::new(ies.clone());
660 ies_updater.remove(&IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00]));
661 assert_eq!(
662 ies_updater.get(&IeType::new_vendor6([0x00, 0x03, 0x7f, 0x01, 0x01, 0x00])),
663 None
664 );
665 assert_eq!(
666 ies_updater.finalize(),
667 &[
668 0, 2, 10, 20, 0xdd, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xaa, 255, 2, 5, 1, ],
672 );
673
674 let mut ies_updater = IesUpdater::new(ies);
675 ies_updater.remove(&IeType::new_extended(5));
676 assert_eq!(ies_updater.get(&IeType::new_extended(5)), None);
677 assert_eq!(
678 ies_updater.finalize(),
679 &[
680 0, 2, 10, 20, 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 0xdd, 0x05, 0x50, 0x6f, 0x9a, 0x1c, 0xaa ],
684 );
685 }
686}