1use crate::{IpV4Addr, Protocol, DSCP};
4
5use byte_struct::*;
6use modular_bitfield::prelude::*;
7use static_assertions::const_assert;
8use ufmt::derive::uDebug;
9
10const_assert!(IpV4Header::BYTE_LEN == 20);
11
12#[derive(ByteStruct, Clone, Copy, uDebug, Debug, PartialEq, Eq)]
15#[byte_struct_be]
16pub struct IpV4Header {
17 pub version_and_header_length: VersionAndHeaderLength,
19 pub dscp: DSCP,
21 pub total_length: u16,
23 pub identification: u16,
25 pub fragmentation: Fragmentation,
27 pub time_to_live: u8,
29 pub protocol: Protocol,
31 pub checksum: u16,
33 pub src_ipaddr: IpV4Addr,
35 pub dst_ipaddr: IpV4Addr,
37}
38
39impl IpV4Header {
40 pub fn to_be_bytes(&self) -> [u8; Self::BYTE_LEN] {
42 let mut bytes = [0_u8; Self::BYTE_LEN];
43 self.write_bytes(&mut bytes);
44 bytes
45 }
46}
47
48#[derive(Clone, Copy, uDebug, Debug, PartialEq, Eq)]
51pub struct IpV4Frame<T>
52where
53 T: ByteStruct,
54{
55 pub header: IpV4Header,
57 pub data: T,
59}
60
61impl<T> ByteStructLen for IpV4Frame<T>
62where
63 T: ByteStruct,
64{
65 const BYTE_LEN: usize = IpV4Header::BYTE_LEN + T::BYTE_LEN;
66}
67
68impl<T> ByteStruct for IpV4Frame<T>
69where
70 T: ByteStruct,
71{
72 fn read_bytes(bytes: &[u8]) -> Self {
73 IpV4Frame::<T> {
74 header: IpV4Header::read_bytes(&bytes[0..IpV4Header::BYTE_LEN]),
75 data: T::read_bytes(&bytes[IpV4Header::BYTE_LEN..]),
76 }
77 }
78
79 fn write_bytes(&self, bytes: &mut [u8]) {
80 self.header.write_bytes(&mut bytes[0..IpV4Header::BYTE_LEN]);
81 self.data.write_bytes(&mut bytes[IpV4Header::BYTE_LEN..]);
82 }
83}
84
85impl<T> IpV4Frame<T>
86where
87 T: ByteStruct,
88{
89 pub fn to_be_bytes(&self) -> [u8; Self::BYTE_LEN] {
91 let mut bytes = [0_u8; Self::BYTE_LEN];
92 self.write_bytes(&mut bytes);
93 bytes
94 }
95}
96
97#[bitfield(bits = 16)]
99#[derive(Clone, Copy, uDebug, Debug, Default, PartialEq, Eq)]
100pub struct Fragmentation {
101 unused: B1,
102 pub do_not_fragment: B1,
104 pub more_fragments: B1,
106 pub offset: B13,
108}
109
110impl ByteStructLen for Fragmentation {
111 const BYTE_LEN: usize = 2;
112}
113
114impl ByteStruct for Fragmentation {
115 fn read_bytes(bytes: &[u8]) -> Self {
116 let mut bytes_to_read = [0_u8; Fragmentation::BYTE_LEN];
118 bytes_to_read.copy_from_slice(&bytes[0..=1]);
119 Fragmentation::from_bytes(bytes_to_read)
120 }
121
122 fn write_bytes(&self, bytes: &mut [u8]) {
123 let bytes_to_write = self.into_bytes();
124 bytes[0] = bytes_to_write[0];
125 bytes[1] = bytes_to_write[1];
126 }
127}
128
129#[bitfield(bits = 8)]
131#[derive(Clone, Copy, uDebug, Debug, Default, PartialEq, Eq)]
132pub struct VersionAndHeaderLength {
133 pub header_length: B4,
135 pub version: B4,
137}
138
139impl ByteStructLen for VersionAndHeaderLength {
140 const BYTE_LEN: usize = 1;
141}
142
143impl ByteStruct for VersionAndHeaderLength {
144 fn read_bytes(bytes: &[u8]) -> Self {
145 VersionAndHeaderLength::from_bytes([bytes[0]])
147 }
148
149 fn write_bytes(&self, bytes: &mut [u8]) {
150 bytes[0] = self.into_bytes()[0];
151 }
152}