diff --git a/ROADMAP.md b/ROADMAP.md index 1e9dd42..efcf5a4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,6 +8,7 @@ - [x] Sync traffic stats - [x] Sync forwarding table - [ ] Fix WS Proxy code - +- [ ] Fix Ctrl-C +- [x] Fix auto-claim IP ## REST API \ No newline at end of file diff --git a/src/device.rs b/src/device.rs index bfe0c73..b142f40 100644 --- a/src/device.rs +++ b/src/device.rs @@ -3,18 +3,38 @@ // This software is licensed under GPL-3 or newer (see LICENSE.md) use parking_lot::Mutex; -use std::{cmp, collections::VecDeque, convert::TryInto, fmt, fs::{self, File}, io::{self, Cursor, Read, Write, Error as IoError, BufReader, BufRead}, net::{Ipv4Addr, UdpSocket}, os::unix::io::AsRawFd, str, str::FromStr, sync::Arc, time::Duration}; +use std::{ + cmp, + collections::VecDeque, + convert::TryInto, + fmt, + fs::{self, File}, + io::{self, BufRead, BufReader, Cursor, Error as IoError, Read, Write}, + net::{Ipv4Addr, UdpSocket}, + os::unix::io::AsRawFd, + str, + str::FromStr, + sync::Arc, + time::Duration, +}; use timeout_io::Reader; use crate::{crypto, error::Error, util::MsgBuffer}; static TUNSETIFF: libc::c_ulong = 1074025674; +#[repr(C)] +#[derive(Copy, Clone)] +struct IfReqDataAddr { + af: libc::c_int, + addr: Ipv4Addr +} + #[repr(C)] union IfReqData { flags: libc::c_short, value: libc::c_int, - addr: (libc::c_short, Ipv4Addr), + addr: IfReqDataAddr, _dummy: [u8; 24], } @@ -382,11 +402,11 @@ fn get_device_addr(ifname: &str) -> io::Result { let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFADDR.try_into().unwrap(), &mut ifreq) }; match res { 0 => { - let af = unsafe { ifreq.data.addr.0 }; + let af = unsafe { ifreq.data.addr.af }; if af as libc::c_int != libc::AF_INET { return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned())); } - let ip = unsafe { ifreq.data.addr.1 }; + let ip = unsafe { ifreq.data.addr.addr }; Ok(ip) } _ => Err(IoError::last_os_error()), @@ -397,7 +417,8 @@ fn get_device_addr(ifname: &str) -> io::Result { fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> { let sock = UdpSocket::bind("0.0.0.0:0")?; let mut ifreq = IfReq::new(ifname); - ifreq.data.addr = (libc::AF_INET as libc::c_short, addr); + ifreq.data.addr.af = libc::AF_INET as libc::c_int; + ifreq.data.addr.addr = addr; let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFADDR.try_into().unwrap(), &mut ifreq) }; match res { 0 => Ok(()), @@ -413,11 +434,11 @@ fn get_device_netmask(ifname: &str) -> io::Result { let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFNETMASK.try_into().unwrap(), &mut ifreq) }; match res { 0 => { - let af = unsafe { ifreq.data.addr.0 }; + let af = unsafe { ifreq.data.addr.af }; if af as libc::c_int != libc::AF_INET { return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned())); } - let ip = unsafe { ifreq.data.addr.1 }; + let ip = unsafe { ifreq.data.addr.addr }; Ok(ip) } _ => Err(IoError::last_os_error()), @@ -428,7 +449,8 @@ fn get_device_netmask(ifname: &str) -> io::Result { fn set_device_netmask(ifname: &str, addr: Ipv4Addr) -> io::Result<()> { let sock = UdpSocket::bind("0.0.0.0:0")?; let mut ifreq = IfReq::new(ifname); - ifreq.data.addr = (libc::AF_INET as libc::c_short, addr); + ifreq.data.addr.af = libc::AF_INET as libc::c_int; + ifreq.data.addr.addr = addr; let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFNETMASK.try_into().unwrap(), &mut ifreq) }; match res { 0 => Ok(()),