]>
code.octet-stream.net Git - netwatcher/blob - src/list_unix.rs
2 use std
::{collections
::HashMap
, net
::IpAddr
};
4 use nix
::{ifaddrs
::getifaddrs
, net
::if_
::if_nametoindex
};
6 use crate::{Error
, Interface
, List
};
8 struct CandidateInterface
{
11 hw_addr
: Option
<String
>,
15 pub(crate) fn list_interfaces() -> Result
<List
, Error
> {
16 let addrs
= getifaddrs().map_err(|_
| Error
::Internal
)?
;
17 let mut candidates
= HashMap
::new();
20 let index
= if_nametoindex(addr
.inter
face
_name
.as_str()).map_err(|_
| Error
::Internal
)?
;
21 let candidate
= candidates
22 .entry(addr
.inter
face
_name
.clone())
23 .or_insert_with(|| CandidateInterface
{
24 name
: addr
.inter
face
_name
.clone(),
29 if let Some(a
) = addr
.address
{
30 if let Some(a
) = a
.as_link_addr() {
31 if let Some(raw_addr
) = a
.addr() {
32 candidate
.hw_addr
= Some(format_mac(&raw_addr
)?
);
35 if let Some(a
) = a
.as_sockaddr_in() {
36 candidate
.ips
.push(IpAddr
::V4(a
.ip
()));
38 if let Some(a
) = a
.as_sockaddr_in6() {
39 candidate
.ips
.push(IpAddr
::V6(a
.ip
()));
47 c
.hw_addr
.map(|hw_addr
| {
63 fn format_mac(bytes
: &[u8]) -> Result
<String
, Error
> {
64 let mut mac
= String
::with_capacity(bytes
.len() * 3);
65 for (i
, b
) in bytes
.iter
().enumerate() {
67 write
!(mac
, ":").map_err(|_
| Error
::Internal
)?
;
69 write
!(mac
, "{:02X}", b
).map_err(|_
| Error
::Internal
)?
;