]>
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(|e
| Error
::Getifaddrs(e
))?
;
17 let mut candidates
= HashMap
::new();
21 if_nametoindex(addr
.inter
face
_name
.as_str()).map_err(|e
| Error
::GetInterfaceName(e
))?
;
22 let candidate
= candidates
23 .entry(addr
.inter
face
_name
.clone())
24 .or_insert_with(|| CandidateInterface
{
25 name
: addr
.inter
face
_name
.clone(),
30 if let Some(a
) = addr
.address
{
31 if let Some(a
) = a
.as_link_addr() {
32 if let Some(raw_addr
) = a
.addr() {
33 candidate
.hw_addr
= Some(format_mac(&raw_addr
)?
);
36 if let Some(a
) = a
.as_sockaddr_in() {
37 candidate
.ips
.push(IpAddr
::V4(a
.ip
()));
39 if let Some(a
) = a
.as_sockaddr_in6() {
40 candidate
.ips
.push(IpAddr
::V6(a
.ip
()));
48 c
.hw_addr
.map(|hw_addr
| {
64 fn format_mac(bytes
: &[u8]) -> Result
<String
, Error
> {
65 let mut mac
= String
::with_capacity(bytes
.len() * 3);
66 for (i
, b
) in bytes
.iter
().enumerate() {
68 write
!(mac
, ":").map_err(|_
| Error
::FormatMacAddress
)?
;
70 write
!(mac
, "{:02X}", b
).map_err(|_
| Error
::FormatMacAddress
)?
;