summaryrefslogtreecommitdiff
path: root/bin/wireguard-show.rs
blob: 17476d6dc5b6e714f559c681590d9ca94853fc61 (plain)
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(),
    }
}