kernel/net/
mod.rs

1pub mod socket;
2
3use core::{any::Any, fmt};
4
5use alloc::{boxed::Box, vec::Vec};
6
7use crate::{devices::net::MacAddress, testing};
8
9/// Represent a part of a network stack, and will
10/// be written directly into the network DMA buffer
11pub trait NetworkHeader: fmt::Debug + Any {
12    fn write_into_buffer(&self, buffer: &mut [u8]) -> Result<(), NetworkError>;
13    fn size(&self) -> usize;
14    fn read_from_buffer(&mut self, buffer: &[u8]) -> Result<usize, NetworkError>;
15    fn create() -> Self
16    where
17        Self: Default,
18    {
19        Default::default()
20    }
21}
22
23#[derive(Debug, Default)]
24pub struct NetworkPacket {
25    headers: Vec<Box<dyn NetworkHeader>>,
26    payload: Vec<u8>,
27}
28
29#[allow(dead_code)]
30impl NetworkPacket {
31    pub fn push<T: NetworkHeader + 'static>(&mut self, header: T) -> &mut Self {
32        self.headers.push(Box::new(header));
33        self
34    }
35
36    pub fn push_empty<T: NetworkHeader + Default + 'static>(&mut self) -> &mut Self {
37        self.headers.push(Box::new(T::create()));
38        self
39    }
40
41    pub fn payload(&self) -> &[u8] {
42        &self.payload
43    }
44
45    pub fn set_payload(&mut self, payload: Vec<u8>) {
46        self.payload = payload;
47    }
48
49    pub fn extend_payload(&mut self, payload: &[u8]) {
50        self.payload.extend_from_slice(payload);
51    }
52
53    pub fn size(&self) -> usize {
54        self.headers.iter().map(|h| h.size()).sum::<usize>() + self.payload.len()
55    }
56
57    pub fn write_into_buffer(&self, buffer: &mut [u8]) -> Result<usize, NetworkError> {
58        if buffer.len() < self.size() {
59            return Err(NetworkError::NotEnoughSpace);
60        }
61
62        let mut offset = 0;
63        for header in self.headers.iter() {
64            header.write_into_buffer(&mut buffer[offset..])?;
65            offset += header.size();
66        }
67
68        let payload_len = self.payload.len();
69
70        buffer[offset..offset + payload_len].copy_from_slice(&self.payload);
71
72        Ok(offset + payload_len)
73    }
74
75    pub fn read_from_buffer(&mut self, buffer: &[u8]) -> Result<(), NetworkError> {
76        let mut offset = 0;
77        for header in self.headers.iter_mut() {
78            offset += header.read_from_buffer(&buffer[offset..])?;
79        }
80        // remaining bytes are the payload
81        self.payload.clear();
82        self.payload.extend_from_slice(&buffer[offset..]);
83
84        Ok(())
85    }
86
87    pub fn header<T: NetworkHeader>(&self) -> Option<&T> {
88        self.headers
89            .iter()
90            .find_map(|h| (h.as_ref() as &dyn Any).downcast_ref::<T>())
91    }
92
93    pub fn headers<T: NetworkHeader>(&self) -> impl Iterator<Item = &T> {
94        self.headers
95            .iter()
96            .filter_map(|h| (h.as_ref() as &dyn Any).downcast_ref::<T>())
97    }
98
99    pub fn all_headers(&self) -> &[Box<dyn NetworkHeader>] {
100        &self.headers
101    }
102}
103
104#[repr(u16)]
105#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
106pub enum EtherType {
107    #[default]
108    Unknown = 0x0000,
109    Ipv4 = 0x0800,
110    Arp = 0x0806,
111    WakeOnLan = 0x0842,
112    Srp = 0x22EA,
113    Avtp = 0x22F0,
114    IetfThrill = 0x22F3,
115    Rarp = 0x8035,
116    VlanFrame = 0x8100,
117    Slpp = 0x8102,
118    Vlacp = 0x8103,
119    Ipx = 0x8137,
120    QnxQnet = 0x8204,
121    Ipv6 = 0x86DD,
122    EthernetFlowControl = 0x8808,
123    PPPoEDiscovery = 0x8863,
124    PPPoESession = 0x8864,
125    AtaOverEthernet = 0x88A2,
126    Lldp = 0x88CC,
127    Mrp = 0x88E3,
128    Ptp = 0x88F7,
129    Prp = 0x88FB,
130}
131
132impl EtherType {
133    pub fn to_be_bytes(self) -> [u8; 2] {
134        (self as u16).to_be_bytes()
135    }
136
137    fn from_be_bytes(num: [u8; 2]) -> Result<Self, NetworkError> {
138        match u16::from_be_bytes(num) {
139            0x0800 => Ok(EtherType::Ipv4),
140            0x0806 => Ok(EtherType::Arp),
141            0x0842 => Ok(EtherType::WakeOnLan),
142            0x22EA => Ok(EtherType::Srp),
143            0x22F0 => Ok(EtherType::Avtp),
144            0x22F3 => Ok(EtherType::IetfThrill),
145            0x8035 => Ok(EtherType::Rarp),
146            0x8100 => Ok(EtherType::VlanFrame),
147            0x8102 => Ok(EtherType::Slpp),
148            0x8103 => Ok(EtherType::Vlacp),
149            0x8137 => Ok(EtherType::Ipx),
150            0x8204 => Ok(EtherType::QnxQnet),
151            0x86DD => Ok(EtherType::Ipv6),
152            0x8808 => Ok(EtherType::EthernetFlowControl),
153            0x8863 => Ok(EtherType::PPPoEDiscovery),
154            0x8864 => Ok(EtherType::PPPoESession),
155            0x88A2 => Ok(EtherType::AtaOverEthernet),
156            0x88CC => Ok(EtherType::Lldp),
157            0x88E3 => Ok(EtherType::Mrp),
158            0x88F7 => Ok(EtherType::Ptp),
159            0x88FB => Ok(EtherType::Prp),
160            num => Err(NetworkError::UnsupporedEtherType(num)),
161        }
162    }
163}
164
165#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
166#[allow(unused)]
167pub struct EthernetHeader {
168    pub dest: MacAddress,
169    pub src: MacAddress,
170    pub ty: EtherType,
171}
172
173impl NetworkHeader for EthernetHeader {
174    fn write_into_buffer(&self, buffer: &mut [u8]) -> Result<(), NetworkError> {
175        buffer[0..6].copy_from_slice(self.dest.bytes());
176        buffer[6..12].copy_from_slice(self.src.bytes());
177        buffer[12..14].copy_from_slice(&self.ty.to_be_bytes());
178        Ok(())
179    }
180
181    fn size(&self) -> usize {
182        14
183    }
184
185    fn read_from_buffer(&mut self, buffer: &[u8]) -> Result<usize, NetworkError> {
186        if buffer.len() < 14 {
187            return Err(NetworkError::ReachedEndOfStream);
188        }
189
190        self.dest = MacAddress::new(buffer[0..6].try_into().unwrap());
191        self.src = MacAddress::new(buffer[6..12].try_into().unwrap());
192        self.ty = EtherType::from_be_bytes(buffer[12..14].try_into().unwrap())?;
193
194        Ok(14)
195    }
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
199#[allow(unused)]
200pub enum NetworkError {
201    ReachedEndOfStream,
202    NotEnoughSpace,
203    UnsupporedEtherType(u16),
204    PacketTooLarge(usize),
205}
206
207#[macro_rules_attribute::apply(testing::test)]
208fn test_parse_ethernet_header() {
209    let mut header = EthernetHeader::default();
210    let buffer = [
211        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, // dest
212        0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, // src
213        0x08, 0x00, // type
214    ];
215
216    assert_eq!(header.read_from_buffer(&buffer), Ok(14));
217    assert_eq!(
218        header.dest,
219        MacAddress::new([0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
220    );
221    assert_eq!(
222        header.src,
223        MacAddress::new([0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B])
224    );
225    assert_eq!(header.ty, EtherType::Ipv4);
226}
227
228#[macro_rules_attribute::apply(testing::test)]
229fn test_parse_packet() {
230    let mut packet = NetworkPacket::default();
231    packet.push(EthernetHeader {
232        dest: MacAddress::new([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
233        src: MacAddress::new([0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B]),
234        ty: EtherType::Ipv4,
235    });
236
237    let mut buffer = [0; 256];
238    assert_eq!(packet.write_into_buffer(&mut buffer), Ok(14));
239
240    let mut packet2 = NetworkPacket::default();
241    packet2.push_empty::<EthernetHeader>();
242    packet2.read_from_buffer(&buffer).unwrap();
243
244    assert_eq!(packet2.payload().len(), 256 - 14);
245    assert!(packet2.payload().iter().all(|&x| x == 0));
246
247    assert_eq!(packet2.all_headers().len(), 1);
248    let header = packet2.header::<EthernetHeader>().unwrap();
249    assert_eq!(header, packet.header::<EthernetHeader>().unwrap());
250    assert_eq!(
251        header.dest,
252        MacAddress::new([0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
253    );
254    assert_eq!(
255        header.src,
256        MacAddress::new([0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B])
257    );
258    assert_eq!(header.ty, EtherType::Ipv4);
259}