1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use super::super::*;
extern crate byteorder;
use self::byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum EtherType {
Ipv4 = 0x0800,
Ipv6 = 0x86dd,
Arp = 0x0806,
WakeOnLan = 0x0842,
VlanTaggedFrame = 0x8100,
ProviderBridging = 0x88A8,
VlanDoubleTaggedFrame = 0x9100
}
impl EtherType {
pub fn from_u16(value: u16) -> Option<EtherType> {
use self::EtherType::*;
match value {
0x0800 => Some(Ipv4),
0x86dd => Some(Ipv6),
0x0806 => Some(Arp),
0x0842 => Some(WakeOnLan),
0x88A8 => Some(ProviderBridging),
0x8100 => Some(VlanTaggedFrame),
0x9100 => Some(VlanDoubleTaggedFrame),
_ => None
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Ethernet2Header {
pub source: [u8;6],
pub destination: [u8;6],
pub ether_type: u16
}
impl SerializedSize for Ethernet2Header {
const SERIALIZED_SIZE: usize = 14;
}
impl Ethernet2Header {
pub fn read<T: io::Read + io::Seek + Sized>(reader: &mut T) -> Result<Ethernet2Header, io::Error> {
fn read_mac_address<T: io::Read>(read: &mut T) -> Result<[u8;6], io::Error> {
let mut result: [u8;6] = [0;6];
read.read_exact(&mut result)?;
Ok(result)
}
Ok(Ethernet2Header {
destination: read_mac_address(reader)?,
source: read_mac_address(reader)?,
ether_type: reader.read_u16::<BigEndian>()?
})
}
pub fn write<T: io::Write + Sized>(&self, writer: &mut T) -> Result<(), io::Error> {
writer.write_all(&self.destination)?;
writer.write_all(&self.source)?;
writer.write_u16::<BigEndian>(self.ether_type)?;
Ok(())
}
}