1use pnet::datalink::{
2 channel, interfaces, Channel, DataLinkReceiver, DataLinkSender, NetworkInterface,
3};
4use std::{
5 io::{Error, ErrorKind},
6 net::{IpAddr, Ipv4Addr},
7 time::Duration,
8};
9
10#[derive(Clone, PartialEq, Eq, Debug, Hash)]
13pub struct Interface {
14 network_interface: NetworkInterface,
15}
16
17impl Interface {
18 pub fn new() -> Result<Self, Error> {
20 match Interface::get_interface_by_guess() {
21 Some(iface) => Ok(Interface {
22 network_interface: iface,
23 }),
24 None => Err(Error::new(
25 ErrorKind::NotConnected,
26 "Could not get any network interface.",
27 )),
28 }
29 }
30
31 pub fn new_by_name(interface_name: &str) -> Option<Self> {
33 let iface = Interface::get_interface_by_name(&interface_name);
34
35 match iface {
36 Some(iface) => Some(Interface {
37 network_interface: iface,
38 }),
39 None => None,
40 }
41 }
42
43 pub fn get_ip(&self) -> Result<Ipv4Addr, Error> {
45 let ip = self
46 .network_interface
47 .ips
48 .iter()
49 .find(|ip| ip.is_ipv4())
50 .map(|ip| match ip.ip() {
51 IpAddr::V4(ip) => Some(ip),
52 _ => None,
53 })
54 .unwrap_or(None);
55
56 match ip {
57 Some(ip) => Ok(ip),
58 None => Err(Error::new(
59 ErrorKind::AddrNotAvailable,
60 "Currently selected interface does not have any IP address assigned.",
61 )),
62 }
63 }
64
65 pub fn get_mac(&self) -> Result<MacAddr, Error> {
67 match self.network_interface.mac {
68 Some(mac) => Ok(mac.into()),
69 None => Err(Error::new(
70 ErrorKind::AddrNotAvailable,
71 "Currently selected interface does not have any MAC address assigned.",
72 )),
73 }
74 }
75
76 pub fn get_raw_interface(&self) -> &NetworkInterface {
78 &self.network_interface
79 }
80
81 pub fn create_tx_rx_channels(
83 &self,
84 ) -> Result<(Box<dyn DataLinkSender>, Box<dyn DataLinkReceiver>), Error> {
85 let channel_config = pnet::datalink::Config {
86 read_timeout: Some(Duration::ZERO),
87 ..Default::default()
88 };
89
90 match channel(&self.get_raw_interface(), channel_config) {
91 Ok(Channel::Ethernet(tx, rx)) => Ok((tx, rx)),
92 Ok(_) => return Err(Error::new(ErrorKind::Other, "Unknown channel type")),
93 Err(err) => return Err(err),
94 }
95 }
96
97 fn get_all_interfaces() -> Vec<NetworkInterface> {
98 interfaces()
99 }
100
101 fn get_interface_by_guess() -> Option<NetworkInterface> {
102 let considered_ifaces = Interface::get_all_interfaces()
103 .into_iter()
104 .filter(|iface| !iface.is_loopback() && iface.is_up() && !iface.ips.is_empty())
105 .collect::<Vec<NetworkInterface>>();
106
107 match considered_ifaces.first() {
108 Some(iface) => Some(iface.clone()),
109 None => None,
110 }
111 }
112
113 fn get_interface_by_name(name: &str) -> Option<NetworkInterface> {
114 let considered_ifaces = Interface::get_all_interfaces()
115 .into_iter()
116 .filter(|iface| iface.name == *name)
117 .collect::<Vec<NetworkInterface>>();
118
119 match considered_ifaces.first() {
120 Some(iface) => Some(iface.clone()),
121 None => None,
122 }
123 }
124}
125
126#[derive(PartialEq, Eq, Clone, Copy)]
128pub struct MacAddr(pub u8, pub u8, pub u8, pub u8, pub u8, pub u8);
129
130impl MacAddr {
131 pub fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> Self {
132 MacAddr(a, b, c, d, e, f)
133 }
134}
135
136impl std::fmt::Display for MacAddr {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 write!(
139 f,
140 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
141 self.0, self.1, self.2, self.3, self.4, self.5
142 )
143 }
144}
145
146impl From<pnet::util::MacAddr> for MacAddr {
147 fn from(pnet_mac_addr: pnet::util::MacAddr) -> Self {
148 MacAddr(
149 pnet_mac_addr.0,
150 pnet_mac_addr.1,
151 pnet_mac_addr.2,
152 pnet_mac_addr.3,
153 pnet_mac_addr.4,
154 pnet_mac_addr.5,
155 )
156 }
157}
158
159impl From<MacAddr> for pnet::util::MacAddr {
160 fn from(mac_addr: MacAddr) -> Self {
161 pnet::util::MacAddr(
162 mac_addr.0, mac_addr.1, mac_addr.2, mac_addr.3, mac_addr.4, mac_addr.5,
163 )
164 }
165}