rips_packets/ethernet/
mod.rs

1mod macaddr;
2pub use self::macaddr::*;
3
4packet!(EthernetPacket, MutEthernetPacket, 14);
5
6getters!(EthernetPacket
7    pub fn destination(&self) -> MacAddr {
8        MacAddr::from_slice(&self.0[0..6])
9    }
10
11    pub fn source(&self) -> MacAddr {
12        MacAddr::from_slice(&self.0[6..12])
13    }
14
15    pub fn ether_type(&self) -> EtherType {
16        EtherType(read_offset!(self.0, 12, u16, from_be))
17    }
18);
19
20setters!(MutEthernetPacket
21    pub fn set_destination(&mut self, destination: MacAddr) {
22        self.0[0..6].copy_from_slice(destination.as_ref());
23    }
24
25    pub fn set_source(&mut self, source: MacAddr) {
26        self.0[6..12].copy_from_slice(source.as_ref());
27    }
28
29    pub fn set_ether_type(&mut self, ether_type: EtherType) {
30        write_offset!(self.0, 12, ether_type.value(), u16, to_be)
31    }
32);
33
34
35/// A representation of the 16 bit EtherType header field of an Ethernet packet.
36///
37/// A few select, commonly used, values are attached as associated constants. Their values are
38/// defined on [IANA's website].
39///
40/// [IANA's website]: https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
41#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
42pub struct EtherType(pub u16);
43
44impl EtherType {
45    pub const IPV4: EtherType = EtherType(0x0800);
46    pub const ARP: EtherType = EtherType(0x0806);
47    pub const IPV6: EtherType = EtherType(0x86DD);
48
49    #[inline]
50    pub fn value(&self) -> u16 {
51        self.0
52    }
53}
54
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    static MAC: [u8; 6] = [0xff; 6];
61
62    macro_rules! eth_setget_test {
63        ($name:ident, $set_name:ident, $value:expr, $offset:expr, $expected:expr) => {
64            setget_test!(MutEthernetPacket, $name, $set_name, $value, $offset, $expected);
65        }
66    }
67
68    eth_setget_test!(destination, set_destination, MacAddr(MAC), 0, MAC);
69    eth_setget_test!(source, set_source, MacAddr(MAC), 6, MAC);
70    eth_setget_test!(ether_type, set_ether_type, EtherType(0xffff), 12, [0xff; 2]);
71
72    #[test]
73    fn set_payload() {
74        let mut backing_data = [0; 15];
75        {
76            let mut testee = MutEthernetPacket::new(&mut backing_data).unwrap();
77            testee.payload()[0] = 99;
78        }
79        assert_eq!(99, backing_data[14]);
80    }
81}