1 use crate::{Ethernet2Header, LinuxSllHeader}; 2 3 /// The possible headers on the link layer 4 #[derive(Clone, Debug, Eq, PartialEq)] 5 pub enum LinkHeader { 6 LinuxSll(LinuxSllHeader), 7 Ethernet2(Ethernet2Header), 8 } 9 10 impl LinkHeader { 11 /// Returns `Option::Some` containing the `Ethernet2Header` if self has the 12 /// value Ethernet2. Otherwise `Option::None` is returned. ethernet2(self) -> Option<Ethernet2Header>13 pub fn ethernet2(self) -> Option<Ethernet2Header> { 14 use crate::LinkHeader::*; 15 if let Ethernet2(value) = self { 16 Some(value) 17 } else { 18 None 19 } 20 } 21 22 /// Returns `Option::Some` containing the `Ethernet2Header` if self has the 23 /// value Ethernet2. Otherwise `Option::None` is returned. mut_ethernet2(&mut self) -> Option<&mut Ethernet2Header>24 pub fn mut_ethernet2(&mut self) -> Option<&mut Ethernet2Header> { 25 use crate::LinkHeader::*; 26 if let Ethernet2(value) = self { 27 Some(value) 28 } else { 29 None 30 } 31 } 32 33 /// Returns `Option::Some` containing the `LinuxSllHeader` if self has the 34 /// value LinuxSll. Otherwise `Option::None` is returned. linux_sll(self) -> Option<LinuxSllHeader>35 pub fn linux_sll(self) -> Option<LinuxSllHeader> { 36 use crate::LinkHeader::*; 37 if let LinuxSll(value) = self { 38 Some(value) 39 } else { 40 None 41 } 42 } 43 44 /// Returns `Option::Some` containing the `LinuxSllHeader` if self has the 45 /// value LinuxSll. Otherwise `Option::None` is returned. mut_linux_sll(&mut self) -> Option<&mut LinuxSllHeader>46 pub fn mut_linux_sll(&mut self) -> Option<&mut LinuxSllHeader> { 47 use crate::LinkHeader::*; 48 if let LinuxSll(value) = self { 49 Some(value) 50 } else { 51 None 52 } 53 } 54 55 /// Returns the size of the link header header_len(&self) -> usize56 pub fn header_len(&self) -> usize { 57 use crate::LinkHeader::*; 58 match self { 59 Ethernet2(_) => Ethernet2Header::LEN, 60 LinuxSll(_) => LinuxSllHeader::LEN, 61 } 62 } 63 64 /// Write the link header to the given writer. 65 #[cfg(feature = "std")] 66 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error>67 pub fn write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error> { 68 use crate::LinkHeader::*; 69 match self { 70 Ethernet2(value) => value.write(writer), 71 LinuxSll(value) => value.write(writer), 72 } 73 } 74 } 75 76 #[cfg(test)] 77 mod test { 78 use super::*; 79 use crate::{test_gens::*, *}; 80 use alloc::{format, vec::Vec}; 81 use proptest::prelude::*; 82 use std::io::Cursor; 83 84 proptest! { 85 #[test] 86 fn debug( 87 ethernet2 in ethernet_2_any(), 88 linux_sll in linux_sll_any(), 89 ) { 90 assert_eq!( 91 format!("Ethernet2({:?})", ethernet2), 92 format!("{:?}", LinkHeader::Ethernet2(ethernet2.clone())), 93 ); 94 assert_eq!( 95 format!("LinuxSll({:?})", linux_sll), 96 format!("{:?}", LinkHeader::LinuxSll(linux_sll.clone())), 97 ); 98 } 99 } 100 101 proptest! { 102 #[test] 103 fn clone_eq( 104 ethernet2 in ethernet_2_any(), 105 linux_sll in linux_sll_any(), 106 ) { 107 let values = [ 108 LinkHeader::Ethernet2(ethernet2), 109 LinkHeader::LinuxSll(linux_sll), 110 ]; 111 for value in values { 112 assert_eq!(value.clone(), value); 113 } 114 } 115 } 116 117 proptest! { 118 #[test] 119 fn ethernet2( 120 ethernet2 in ethernet_2_any(), 121 linux_sll in linux_sll_any() 122 ) { 123 assert_eq!(Some(ethernet2.clone()), LinkHeader::Ethernet2(ethernet2).ethernet2()); 124 assert_eq!(None, LinkHeader::LinuxSll(linux_sll).ethernet2()); 125 } 126 127 } 128 proptest! { 129 #[test] 130 fn mut_ethernet2( 131 ethernet2 in ethernet_2_any(), 132 linux_sll in linux_sll_any() 133 ) { 134 assert_eq!(Some(&mut ethernet2.clone()), LinkHeader::Ethernet2(ethernet2).mut_ethernet2()); 135 assert_eq!(None, LinkHeader::LinuxSll(linux_sll).mut_ethernet2()); 136 } 137 } 138 139 proptest! { 140 #[test] 141 fn linux_sll( 142 ethernet2 in ethernet_2_any(), 143 linux_sll in linux_sll_any() 144 ) { 145 assert_eq!(Some(linux_sll.clone()), LinkHeader::LinuxSll(linux_sll).linux_sll()); 146 assert_eq!(None, LinkHeader::Ethernet2(ethernet2).linux_sll()); 147 } 148 149 } 150 proptest! { 151 #[test] 152 fn mut_linux_sll( 153 ethernet2 in ethernet_2_any(), 154 linux_sll in linux_sll_any() 155 ) { 156 assert_eq!(Some(&mut linux_sll.clone()), LinkHeader::LinuxSll(linux_sll).mut_linux_sll()); 157 assert_eq!(None, LinkHeader::Ethernet2(ethernet2).mut_linux_sll()); 158 } 159 } 160 161 proptest! { 162 #[test] 163 fn header_size( 164 ethernet2 in ethernet_2_any(), 165 linux_sll in linux_sll_any() 166 ) { 167 assert_eq!( 168 LinkHeader::Ethernet2(ethernet2).header_len(), 169 Ethernet2Header::LEN 170 ); 171 assert_eq!( 172 LinkHeader::LinuxSll(linux_sll.clone()).header_len(), 173 LinuxSllHeader::LEN 174 ); 175 } 176 } 177 178 proptest! { 179 #[test] 180 fn write( 181 ethernet2 in ethernet_2_any(), 182 linux_sll in linux_sll_any() 183 ) { 184 // ethernet2 185 { 186 //write 187 { 188 let result_input = { 189 let mut buffer = Vec::new(); 190 ethernet2.write(&mut buffer).unwrap(); 191 buffer 192 }; 193 let result_transport = { 194 let mut buffer = Vec::new(); 195 LinkHeader::Ethernet2(ethernet2.clone()).write(&mut buffer).unwrap(); 196 buffer 197 }; 198 assert_eq!(result_input, result_transport); 199 } 200 //trigger an error 201 { 202 let mut a: [u8;0] = []; 203 assert!( 204 LinkHeader::Ethernet2(ethernet2.clone()) 205 .write(&mut Cursor::new(&mut a[..])) 206 .is_err() 207 ); 208 } 209 } 210 // linux_sll 211 { 212 //write 213 { 214 let result_input = { 215 let mut buffer = Vec::new(); 216 linux_sll.write(&mut buffer).unwrap(); 217 buffer 218 }; 219 let result_transport = { 220 let mut buffer = Vec::new(); 221 LinkHeader::LinuxSll(linux_sll.clone()).write(&mut buffer).unwrap(); 222 buffer 223 }; 224 assert_eq!(result_input, result_transport); 225 } 226 //trigger an error 227 { 228 let mut a: [u8;0] = []; 229 assert!( 230 LinkHeader::LinuxSll(linux_sll.clone()) 231 .write(&mut Cursor::new(&mut a[..])) 232 .is_err() 233 ); 234 } 235 } 236 } 237 } 238 } 239