1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4
5use netlink_packet_utils::DecodeError;
6
7pub(crate) const IPV4_ADDR_LEN: usize = 4;
8pub(crate) const IPV6_ADDR_LEN: usize = 16;
9
10pub(crate) fn parse_ipv4_addr(raw: &[u8]) -> Result<Ipv4Addr, DecodeError> {
11 if raw.len() == IPV4_ADDR_LEN {
12 Ok(Ipv4Addr::new(raw[0], raw[1], raw[2], raw[3]))
13 } else {
14 Err(DecodeError::from(format!(
15 "Invalid u8 array length {}, expecting \
16 {IPV4_ADDR_LEN} for IPv4 address, got {:?}",
17 raw.len(),
18 raw,
19 )))
20 }
21}
22
23pub(crate) fn parse_ipv6_addr(raw: &[u8]) -> Result<Ipv6Addr, DecodeError> {
24 if raw.len() == IPV6_ADDR_LEN {
25 let mut data = [0u8; IPV6_ADDR_LEN];
26 data.copy_from_slice(raw);
27 Ok(Ipv6Addr::from(data))
28 } else {
29 Err(DecodeError::from(format!(
30 "Invalid u8 array length {}, expecting {IPV6_ADDR_LEN} \
31 for IPv6 address, got {:?}",
32 raw.len(),
33 raw,
34 )))
35 }
36}
37
38pub(crate) fn emit_ip_to_buffer(ip: &IpAddr, buffer: &mut [u8]) {
39 match ip {
40 IpAddr::V4(ip) => buffer.copy_from_slice(&ip.octets()),
41 IpAddr::V6(ip) => buffer.copy_from_slice(&ip.octets()),
42 }
43}
44
45pub(crate) fn parse_ip_addr(raw: &[u8]) -> Result<IpAddr, DecodeError> {
46 if raw.len() == IPV6_ADDR_LEN {
47 parse_ipv6_addr(raw).map(IpAddr::from)
48 } else if raw.len() == IPV4_ADDR_LEN {
49 parse_ipv4_addr(raw).map(IpAddr::from)
50 } else {
51 Err(DecodeError::from(format!(
52 "Invalid u8 array length {}, expecting {IPV6_ADDR_LEN} \
53 for IPv6 address or {IPV4_ADDR_LEN} for IPv4 address, got {:?}",
54 raw.len(),
55 raw,
56 )))
57 }
58}
59
60pub(crate) fn ip_addr_len(addr: &IpAddr) -> usize {
61 if addr.is_ipv4() {
62 IPV4_ADDR_LEN
63 } else {
64 IPV6_ADDR_LEN
65 }
66}
67
68pub(crate) fn emit_ip_addr(addr: &IpAddr, buffer: &mut [u8]) {
69 match addr {
70 IpAddr::V4(ip) => buffer.copy_from_slice(&ip.octets()),
71 IpAddr::V6(ip) => buffer.copy_from_slice(&ip.octets()),
72 }
73}
74
75const IPPROTO_HOPOPTS: i32 = 0;
78const IPPROTO_ICMP: i32 = 1;
79const IPPROTO_IGMP: i32 = 2;
80const IPPROTO_IPIP: i32 = 4;
81const IPPROTO_TCP: i32 = 6;
82const IPPROTO_EGP: i32 = 8;
83const IPPROTO_PUP: i32 = 12;
84const IPPROTO_UDP: i32 = 17;
85const IPPROTO_IDP: i32 = 22;
86const IPPROTO_TP: i32 = 29;
87const IPPROTO_DCCP: i32 = 33;
88const IPPROTO_IPV6: i32 = 41;
89const IPPROTO_RSVP: i32 = 46;
90const IPPROTO_GRE: i32 = 47;
91const IPPROTO_ESP: i32 = 50;
92const IPPROTO_AH: i32 = 51;
93const IPPROTO_MTP: i32 = 92;
94const IPPROTO_BEETPH: i32 = 94;
95const IPPROTO_ENCAP: i32 = 98;
96const IPPROTO_PIM: i32 = 103;
97const IPPROTO_COMP: i32 = 108;
98const IPPROTO_L2TP: i32 = 115;
99const IPPROTO_SCTP: i32 = 132;
100const IPPROTO_UDPLITE: i32 = 136;
101const IPPROTO_MPLS: i32 = 137;
102const IPPROTO_ETHERNET: i32 = 143;
103const IPPROTO_RAW: i32 = 255;
104const IPPROTO_MPTCP: i32 = 262;
105
106#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
107#[non_exhaustive]
108pub enum IpProtocol {
109 Hopopts,
110 Icmp,
111 Igmp,
112 Ipip,
113 Tcp,
114 Egp,
115 Pup,
116 Udp,
117 Idp,
118 Tp,
119 Dccp,
120 Ipv6,
121 Rsvp,
122 Gre,
123 Esp,
124 Ah,
125 Mtp,
126 Beetph,
127 Encap,
128 Pim,
129 Comp,
130 L2tp,
131 Sctp,
132 Udplite,
133 Mpls,
134 Ethernet,
135 #[default]
136 Raw,
137 Mptcp,
138 Other(i32),
139}
140
141impl From<i32> for IpProtocol {
142 fn from(d: i32) -> Self {
143 match d {
144 IPPROTO_HOPOPTS => Self::Hopopts,
145 IPPROTO_ICMP => Self::Icmp,
146 IPPROTO_IGMP => Self::Igmp,
147 IPPROTO_IPIP => Self::Ipip,
148 IPPROTO_TCP => Self::Tcp,
149 IPPROTO_EGP => Self::Egp,
150 IPPROTO_PUP => Self::Pup,
151 IPPROTO_UDP => Self::Udp,
152 IPPROTO_IDP => Self::Idp,
153 IPPROTO_TP => Self::Tp,
154 IPPROTO_DCCP => Self::Dccp,
155 IPPROTO_IPV6 => Self::Ipv6,
156 IPPROTO_RSVP => Self::Rsvp,
157 IPPROTO_GRE => Self::Gre,
158 IPPROTO_ESP => Self::Esp,
159 IPPROTO_AH => Self::Ah,
160 IPPROTO_MTP => Self::Mtp,
161 IPPROTO_BEETPH => Self::Beetph,
162 IPPROTO_ENCAP => Self::Encap,
163 IPPROTO_PIM => Self::Pim,
164 IPPROTO_COMP => Self::Comp,
165 IPPROTO_L2TP => Self::L2tp,
166 IPPROTO_SCTP => Self::Sctp,
167 IPPROTO_UDPLITE => Self::Udplite,
168 IPPROTO_MPLS => Self::Mpls,
169 IPPROTO_ETHERNET => Self::Ethernet,
170 IPPROTO_RAW => Self::Raw,
171 IPPROTO_MPTCP => Self::Mptcp,
172 _ => Self::Other(d),
173 }
174 }
175}
176
177impl From<IpProtocol> for i32 {
178 fn from(v: IpProtocol) -> i32 {
179 match v {
180 IpProtocol::Hopopts => IPPROTO_HOPOPTS,
181 IpProtocol::Icmp => IPPROTO_ICMP,
182 IpProtocol::Igmp => IPPROTO_IGMP,
183 IpProtocol::Ipip => IPPROTO_IPIP,
184 IpProtocol::Tcp => IPPROTO_TCP,
185 IpProtocol::Egp => IPPROTO_EGP,
186 IpProtocol::Pup => IPPROTO_PUP,
187 IpProtocol::Udp => IPPROTO_UDP,
188 IpProtocol::Idp => IPPROTO_IDP,
189 IpProtocol::Tp => IPPROTO_TP,
190 IpProtocol::Dccp => IPPROTO_DCCP,
191 IpProtocol::Ipv6 => IPPROTO_IPV6,
192 IpProtocol::Rsvp => IPPROTO_RSVP,
193 IpProtocol::Gre => IPPROTO_GRE,
194 IpProtocol::Esp => IPPROTO_ESP,
195 IpProtocol::Ah => IPPROTO_AH,
196 IpProtocol::Mtp => IPPROTO_MTP,
197 IpProtocol::Beetph => IPPROTO_BEETPH,
198 IpProtocol::Encap => IPPROTO_ENCAP,
199 IpProtocol::Pim => IPPROTO_PIM,
200 IpProtocol::Comp => IPPROTO_COMP,
201 IpProtocol::L2tp => IPPROTO_L2TP,
202 IpProtocol::Sctp => IPPROTO_SCTP,
203 IpProtocol::Udplite => IPPROTO_UDPLITE,
204 IpProtocol::Mpls => IPPROTO_MPLS,
205 IpProtocol::Ethernet => IPPROTO_ETHERNET,
206 IpProtocol::Raw => IPPROTO_RAW,
207 IpProtocol::Mptcp => IPPROTO_MPTCP,
208 IpProtocol::Other(d) => d,
209 }
210 }
211}