iris_core/protocols/packet/
ethernet.rs1use crate::memory::mbuf::Mbuf;
4use crate::protocols::packet::{Packet, PacketHeader, PacketParseError};
5use crate::utils::types::*;
6
7use pnet::datalink::MacAddr;
8
9const VLAN_802_1Q: u16 = 0x8100;
10const VLAN_802_1AD: u16 = 0x88a8;
11
12const TAG_SIZE: usize = 4;
13const HDR_SIZE: usize = 14;
14const HDR_SIZE_802_1Q: usize = HDR_SIZE + TAG_SIZE;
15const HDR_SIZE_802_1AD: usize = HDR_SIZE_802_1Q + TAG_SIZE;
16
17#[derive(Debug)]
22pub struct Ethernet<'a> {
23 header: EthernetHeader,
25 offset: usize,
27 mbuf: &'a Mbuf,
29}
30
31impl Ethernet<'_> {
32 #[inline]
34 pub fn dst(&self) -> MacAddr {
35 self.header.dst
36 }
37
38 #[inline]
40 pub fn src(&self) -> MacAddr {
41 self.header.src
42 }
43
44 #[inline]
47 pub fn ether_type(&self) -> u16 {
48 self.next_header().unwrap_or(0) as u16
49 }
50
51 pub fn tci(&self) -> Option<u16> {
54 let ether_type: u16 = u16::from(self.header.ether_type);
55 match ether_type {
56 VLAN_802_1Q => {
57 if let Ok(dot1q) = self.mbuf.get_data(HDR_SIZE) {
58 let dot1q: Dot1q = unsafe { *dot1q };
59 Some(dot1q.tci.into())
60 } else {
61 None
62 }
63 }
64 _ => None,
65 }
66 }
67}
68
69impl<'a> Packet<'a> for Ethernet<'a> {
70 fn mbuf(&self) -> &Mbuf {
71 self.mbuf
72 }
73
74 fn header_len(&self) -> usize {
75 self.header.length()
76 }
77
78 fn next_header_offset(&self) -> usize {
79 self.offset + self.header_len()
80 }
81
82 fn next_header(&self) -> Option<usize> {
83 let ether_type: u16 = u16::from(self.header.ether_type);
84 match ether_type {
85 VLAN_802_1Q => {
86 if let Ok(dot1q) = self.mbuf.get_data(HDR_SIZE) {
87 let dot1q: Dot1q = unsafe { *dot1q };
88 Some(u16::from(dot1q.ether_type).into())
89 } else {
90 None
91 }
92 }
93 VLAN_802_1AD => {
94 None
96 }
97 _ => Some(ether_type.into()),
98 }
99 }
100
101 fn parse_from(outer: &'a impl Packet<'a>) -> Result<Self, PacketParseError>
102 where
103 Self: Sized,
104 {
105 if let Ok(header) = outer.mbuf().get_data(0) {
106 Ok(Ethernet {
107 header: unsafe { *header },
108 offset: 0,
109 mbuf: outer.mbuf(),
110 })
111 } else {
112 Err(PacketParseError::InvalidRead)
113 }
114 }
115}
116
117#[derive(Debug, Clone, Copy)]
119#[repr(C, packed)]
120struct EthernetHeader {
121 dst: MacAddr,
122 src: MacAddr,
123 ether_type: u16be,
124}
125
126impl PacketHeader for EthernetHeader {
127 fn length(&self) -> usize {
128 match self.ether_type.into() {
129 VLAN_802_1Q => HDR_SIZE_802_1Q,
130 VLAN_802_1AD => HDR_SIZE_802_1AD,
131 _ => HDR_SIZE,
132 }
133 }
134}
135
136#[derive(Debug, Clone, Copy)]
142#[repr(C, packed)]
143struct Dot1q {
144 tci: u16be,
145 ether_type: u16be,
146}
147
148impl PacketHeader for Dot1q {
149 fn length(&self) -> usize {
152 TAG_SIZE
153 }
154}
155
156