netlink_packet_route/route/
address.rs1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4
5use netlink_packet_core::{DecodeError, Emitable};
6
7use crate::{
8 ip::{
9 emit_ip_to_buffer, parse_ipv4_addr, parse_ipv6_addr, IPV4_ADDR_LEN,
10 IPV6_ADDR_LEN,
11 },
12 route::MplsLabel,
13 AddressFamily,
14};
15
16#[derive(Debug, PartialEq, Eq, Clone)]
17#[non_exhaustive]
18pub enum RouteAddress {
19 Inet(Ipv4Addr),
20 Inet6(Ipv6Addr),
21 Mpls(MplsLabel),
22 Other(Vec<u8>),
23}
24
25impl From<IpAddr> for RouteAddress {
26 fn from(ip: IpAddr) -> Self {
27 match ip {
28 IpAddr::V4(ipv4) => Self::Inet(ipv4),
29 IpAddr::V6(ipv6) => Self::Inet6(ipv6),
30 }
31 }
32}
33
34impl RouteAddress {
35 pub(crate) fn parse(
36 address_family: AddressFamily,
37 payload: &[u8],
38 ) -> Result<Self, DecodeError> {
39 Ok(match address_family {
40 AddressFamily::Inet => Self::Inet(parse_ipv4_addr(payload)?),
41 AddressFamily::Inet6 => Self::Inet6(parse_ipv6_addr(payload)?),
42 #[cfg(any(target_os = "linux", target_os = "fuchsia"))]
43 AddressFamily::Mpls => Self::Mpls(MplsLabel::parse(payload)?),
44 _ => Self::Other(payload.to_vec()),
45 })
46 }
47}
48
49impl Emitable for RouteAddress {
50 fn buffer_len(&self) -> usize {
51 match self {
52 Self::Inet(_) => IPV4_ADDR_LEN,
53 Self::Inet6(_) => IPV6_ADDR_LEN,
54 Self::Mpls(v) => v.buffer_len(),
55 Self::Other(v) => v.len(),
56 }
57 }
58
59 fn emit(&self, buffer: &mut [u8]) {
60 match self {
61 Self::Inet(v) => emit_ip_to_buffer(&((*v).into()), buffer),
62 Self::Inet6(v) => emit_ip_to_buffer(&((*v).into()), buffer),
63 Self::Mpls(v) => v.emit(buffer),
64 Self::Other(v) => buffer.copy_from_slice(v.as_slice()),
65 }
66 }
67}
68
69impl From<Ipv4Addr> for RouteAddress {
70 fn from(v: Ipv4Addr) -> Self {
71 Self::Inet(v)
72 }
73}
74
75impl From<Ipv6Addr> for RouteAddress {
76 fn from(v: Ipv6Addr) -> Self {
77 Self::Inet6(v)
78 }
79}
80
81impl From<MplsLabel> for RouteAddress {
82 fn from(v: MplsLabel) -> Self {
83 Self::Mpls(v)
84 }
85}