1#[cfg(all(target_os = "linux", feature = "netlink"))]
2use neli::consts::rtnl::{RtScope, RtmF, Rtn, Rtprot};
3use std::net::Ipv4Addr;
4
5#[derive(Debug)]
6pub struct RouteGetResponse {
7 pub routes: Vec<Route>,
8}
9
10#[derive(Debug)]
11pub struct Route {
12 pub dst: Option<Ipv4Addr>,
13 pub dst_prefix_len: u8,
14 pub gateway: Option<Ipv4Addr>,
15 pub prefsrc: Option<Ipv4Addr>,
16 pub oif_name: Option<String>,
17 pub protocol: RouteProtocol,
18 pub scope: RouteScope,
19 pub route_type: RouteType,
20 pub metric: Option<u32>,
21 pub flags: RouteFlags,
22}
23
24#[derive(Debug, Default, Clone, Copy)]
25pub struct RouteFlags {
26 pub dead: bool,
27 pub pervasive: bool,
28 pub onlink: bool,
29 pub offload: bool,
30 pub linkdown: bool,
31 pub unresolved: bool,
32 pub trap: bool,
33}
34
35#[cfg(all(target_os = "linux", feature = "netlink"))]
36impl From<RtmF> for RouteFlags {
37 fn from(value: RtmF) -> Self {
38 let bits: u32 = value.into();
39
40 const RTNH_F_DEAD: u32 = 1;
43 const RTNH_F_PERVASIVE: u32 = 2;
44 const RTNH_F_ONLINK: u32 = 4;
45 const RTNH_F_OFFLOAD: u32 = 8;
46 const RTNH_F_LINKDOWN: u32 = 16;
47 const RTNH_F_UNRESOLVED: u32 = 32;
48 const RTNH_F_TRAP: u32 = 64;
49
50 RouteFlags {
51 dead: bits & RTNH_F_DEAD != 0,
52 pervasive: bits & RTNH_F_PERVASIVE != 0,
53 onlink: bits & RTNH_F_ONLINK != 0,
54 offload: bits & RTNH_F_OFFLOAD != 0,
55 linkdown: bits & RTNH_F_LINKDOWN != 0,
56 unresolved: bits & RTNH_F_UNRESOLVED != 0,
57 trap: bits & RTNH_F_TRAP != 0,
58 }
59 }
60}
61#[derive(Debug, Clone, Copy, PartialEq)]
62pub enum RouteProtocol {
63 Unspec,
64 Redirect,
65 Kernel,
66 Boot,
67 Static,
68 Dhcp,
69 Other(u8),
70}
71
72#[cfg(all(target_os = "linux", feature = "netlink"))]
73impl From<Rtprot> for RouteProtocol {
74 fn from(p: Rtprot) -> Self {
75 match p {
76 Rtprot::Unspec => RouteProtocol::Unspec,
77 Rtprot::Redirect => RouteProtocol::Redirect,
78 Rtprot::Kernel => RouteProtocol::Kernel,
79 Rtprot::Boot => RouteProtocol::Boot,
80 Rtprot::Static => RouteProtocol::Static,
81 Rtprot::UnrecognizedConst(16) => RouteProtocol::Dhcp,
82 Rtprot::UnrecognizedConst(v) => RouteProtocol::Other(v),
83 }
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq)]
88pub enum RouteScope {
89 Universe,
90 Site,
91 Link,
92 Host,
93 Nowhere,
94 Other(u8),
95}
96
97#[cfg(all(target_os = "linux", feature = "netlink"))]
98impl From<RtScope> for RouteScope {
99 fn from(s: RtScope) -> Self {
100 match s {
101 RtScope::Universe => RouteScope::Universe,
102 RtScope::Site => RouteScope::Site,
103 RtScope::Link => RouteScope::Link,
104 RtScope::Host => RouteScope::Host,
105 RtScope::Nowhere => RouteScope::Nowhere,
106 RtScope::UnrecognizedConst(v) => RouteScope::Other(v),
107 }
108 }
109}
110
111#[derive(Debug, Clone, Copy, PartialEq)]
112pub enum RouteType {
113 Unspec,
114 Unicast,
115 Local,
116 Broadcast,
117 Anycast,
118 Multicast,
119 Blackhole,
120 Unreachable,
121 Prohibit,
122 Throw,
123 Nat,
124 Xresolve,
125 Other(u8),
126}
127#[cfg(all(target_os = "linux", feature = "netlink"))]
128impl From<Rtn> for RouteType {
129 fn from(value: Rtn) -> Self {
130 match value {
131 Rtn::Unspec => RouteType::Unspec,
132 Rtn::Unicast => RouteType::Unicast,
133 Rtn::Local => RouteType::Local,
134 Rtn::Broadcast => RouteType::Broadcast,
135 Rtn::Anycast => RouteType::Anycast,
136 Rtn::Multicast => RouteType::Multicast,
137 Rtn::Blackhole => RouteType::Blackhole,
138 Rtn::Unreachable => RouteType::Unreachable,
139 Rtn::Prohibit => RouteType::Prohibit,
140 Rtn::Throw => RouteType::Throw,
141 Rtn::Nat => RouteType::Nat,
142 Rtn::Xresolve => RouteType::Xresolve,
143 Rtn::UnrecognizedConst(v) => RouteType::Other(v),
144 }
145 }
146}