1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
use anyhow::Result;
use wireguard::WireGuard;
#[tokio::main]
async fn main() -> Result<()> {
let mut wireguard = WireGuard::new().await?;
let devices = wireguard.view_devices().await?;
if devices.is_empty() {
println!("no wireguard devices found");
return Ok(());
}
for device in devices {
println!("device: {}", device.name);
println!(" ifindex: {}", device.ifindex);
println!(" private_key: {}", format_optional_key(device.private_key));
println!(" public_key: {}", format_optional_key(device.public_key));
println!(" listen_port: {}", device.listen_port);
println!(" fwmark: {}", device.fwmark);
println!(" peers: {}", device.peers.len());
for (index, peer) in device.peers.iter().enumerate() {
println!(" peer {}:", index + 1);
println!(" public_key: {}", peer.public_key);
println!(
" preshared_key: {}",
format_optional_key(peer.preshared_key)
);
println!(
" endpoint: {}",
peer.endpoint
.map(|endpoint| endpoint.to_string())
.unwrap_or_else(|| "none".to_string())
);
println!(
" persistent_keepalive: {}",
peer.persistent_keepalive
.map(|keepalive| keepalive.to_string())
.unwrap_or_else(|| "none".to_string())
);
println!(
" last_handshake: {}",
format_duration(peer.last_handshake)
);
println!(" rx_bytes: {}", peer.rx_bytes);
println!(" tx_bytes: {}", peer.tx_bytes);
if peer.allowed_ips.is_empty() {
println!(" allowed_ips: none");
} else {
let allowed_ips = peer
.allowed_ips
.iter()
.map(|ip| ip.to_string())
.collect::<Vec<_>>()
.join(", ");
println!(" allowed_ips: {}", allowed_ips);
}
}
println!();
}
Ok(())
}
fn format_optional_key(key: Option<wireguard::Key>) -> String {
key.map(|value| value.to_string())
.unwrap_or_else(|| "none".to_string())
}
fn format_duration(time: Option<std::time::SystemTime>) -> String {
match time {
Some(time) => match time.duration_since(std::time::UNIX_EPOCH) {
Ok(duration) => format!("{}.{}", duration.as_secs(), duration.subsec_nanos()),
Err(_) => "before-epoch".to_string(),
},
None => "none".to_string(),
}
}
|