icmptunnel_rs/
configure_network.rs

1use crate::constants::MAX_PAYLOAD_SIZE;
2use std::fs::OpenOptions;
3use std::io;
4use std::io::Write;
5use std::net::IpAddr;
6use std::process::Command;
7
8fn write_proc(path: &str, content: &[u8]) -> io::Result<()> {
9    let mut file = OpenOptions::new().write(true).open(path)?;
10    file.write_all(content)?;
11    Ok(())
12}
13
14pub fn configure_server_network() -> io::Result<()> {
15    Command::new("ifconfig")
16        .args([
17            "tun0",
18            "mtu",
19            &(MAX_PAYLOAD_SIZE - 4).to_string(),
20            "up",
21            "10.0.1.1",
22            "netmask",
23            "255.255.255.0",
24        ])
25        .output()?;
26    write_proc("/proc/sys/net/ipv4/icmp_echo_ignore_all", b"1")?;
27    write_proc("/proc/sys/net/ipv4/ip_forward", b"1")?;
28    // iptables nat
29    Command::new("iptables")
30        .args([
31            "-t",
32            "nat",
33            "-A",
34            "POSTROUTING",
35            "-s",
36            "10.0.1.0/24",
37            "-j",
38            "MASQUERADE",
39        ])
40        .output()?;
41    Ok(())
42}
43
44pub fn restore_server_network() -> io::Result<()> {
45    write_proc("/proc/sys/net/ipv4/icmp_echo_ignore_all", b"0")?;
46    Ok(())
47}
48
49pub fn get_gateway_interface() -> io::Result<(String, String)> {
50    let routing_info = Command::new("route").arg("-n").output()?;
51    let str_stdout = String::from_utf8_lossy(&routing_info.stdout);
52    for line in str_stdout.lines() {
53        if line.starts_with("0.0.0.0") {
54            let columns = line
55                .split(" ")
56                .filter(|s| !s.is_empty())
57                .collect::<Vec<&str>>();
58            let gateway = columns[1];
59            let interface = columns[columns.len() - 1];
60            return Ok((gateway.to_string(), interface.to_string()));
61        }
62    }
63    Err(io::Error::new(
64        io::ErrorKind::NotFound,
65        "No default route found",
66    ))
67}
68
69pub fn configure_client_network(server: IpAddr, client_id: u8) -> io::Result<()> {
70    Command::new("ifconfig")
71        .args([
72            "tun0",
73            "mtu",
74            &(MAX_PAYLOAD_SIZE - 4).to_string(),
75            "up",
76            &format!("10.0.1.{client_id}"),
77            "netmask",
78            "255.255.255.0",
79        ])
80        .output()?;
81    let (gateway, interface) = get_gateway_interface()?;
82    Command::new("route")
83        .args([
84            "del", "-net", "0.0.0.0", "gw", &gateway, "netmask", "0.0.0.0", "dev", &interface,
85        ])
86        .output()?;
87    Command::new("route")
88        .args([
89            "add",
90            "-host",
91            &server.to_string(),
92            "gw",
93            &gateway,
94            "dev",
95            &interface,
96        ])
97        .output()?;
98    Command::new("route")
99        .args(["add", "default", "gw", "10.0.1.1", "tun0"])
100        .output()?;
101    Ok(())
102}
103
104pub fn restore_client_network(gateway: String, interface: String) -> io::Result<()> {
105    Command::new("route")
106        .args(["add", "default", "gw", &gateway, "dev", &interface])
107        .output()?;
108    Ok(())
109}