iris_core/protocols/packet/
ipv6.rs1use crate::memory::mbuf::Mbuf;
4use crate::protocols::packet::{Packet, PacketHeader, PacketParseError};
5use crate::utils::types::*;
6
7use std::net::Ipv6Addr;
8
9const IPV6_PROTOCOL: usize = 0x86DD;
10const IPV6_HEADER_LEN: usize = 40;
11
12#[derive(Debug)]
16pub struct Ipv6<'a> {
17 header: Ipv6Header,
19 offset: usize,
21 mbuf: &'a Mbuf,
23}
24
25impl Ipv6<'_> {
26 #[inline]
28 pub fn version(&self) -> u8 {
29 let v: u32 = (self.header.version_to_flow_label & u32be::from(0xf000_0000)).into();
30 (v >> 28) as u8
31 }
32
33 #[inline]
35 pub fn dscp(&self) -> u8 {
36 let v: u32 = (self.header.version_to_flow_label & u32be::from(0x0fc0_0000)).into();
37 (v >> 22) as u8
38 }
39
40 #[inline]
42 pub fn ecn(&self) -> u8 {
43 let v: u32 = (self.header.version_to_flow_label & u32be::from(0x0030_0000)).into();
44 (v >> 20) as u8
45 }
46
47 #[inline]
49 pub fn traffic_class(&self) -> u8 {
50 let v: u32 = (self.header.version_to_flow_label & u32be::from(0x0ff0_0000)).into();
51 (v >> 20) as u8
52 }
53
54 #[inline]
56 pub fn flow_label(&self) -> u32 {
57 (self.header.version_to_flow_label & u32be::from(0x000f_ffff)).into()
58 }
59
60 #[inline]
62 pub fn version_to_flow_label(&self) -> u32 {
63 self.header.version_to_flow_label.into()
64 }
65
66 #[inline]
68 pub fn payload_length(&self) -> u16 {
69 self.header.payload_length.into()
70 }
71
72 #[inline]
74 pub fn next_header(&self) -> u8 {
75 self.header.next_header
76 }
77
78 #[inline]
80 pub fn hop_limit(&self) -> u8 {
81 self.header.hop_limit
82 }
83
84 #[inline]
86 pub fn src_addr(&self) -> Ipv6Addr {
87 self.header.src_addr
88 }
89
90 #[inline]
92 pub fn dst_addr(&self) -> Ipv6Addr {
93 self.header.dst_addr
94 }
95}
96
97impl<'a> Packet<'a> for Ipv6<'a> {
98 fn mbuf(&self) -> &Mbuf {
99 self.mbuf
100 }
101
102 fn header_len(&self) -> usize {
103 self.header.length()
104 }
105
106 fn next_header_offset(&self) -> usize {
107 self.offset + self.header_len()
108 }
109
110 fn next_header(&self) -> Option<usize> {
111 Some(self.next_header().into())
112 }
113
114 fn parse_from(outer: &'a impl Packet<'a>) -> Result<Self, PacketParseError>
115 where
116 Self: Sized,
117 {
118 let offset = outer.next_header_offset();
119 if let Ok(header) = outer.mbuf().get_data(offset) {
120 match outer.next_header() {
121 Some(IPV6_PROTOCOL) => Ok(Ipv6 {
122 header: unsafe { *header },
123 offset,
124 mbuf: outer.mbuf(),
125 }),
126 _ => Err(PacketParseError::InvalidProtocol),
127 }
128 } else {
129 Err(PacketParseError::InvalidRead)
130 }
131 }
132}
133
134#[derive(Debug, Clone, Copy)]
136#[repr(C)]
137struct Ipv6Header {
138 version_to_flow_label: u32be,
139 payload_length: u16be,
140 next_header: u8,
141 hop_limit: u8,
142 src_addr: Ipv6Addr,
143 dst_addr: Ipv6Addr,
144}
145
146impl PacketHeader for Ipv6Header {
147 fn length(&self) -> usize {
149 IPV6_HEADER_LEN
150 }
151}