rips_packets/ethernet/
mod.rs1mod 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#[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}