diff options
Diffstat (limited to '.config/awesome/quarrel/native/src/net/mod.rs')
-rw-r--r-- | .config/awesome/quarrel/native/src/net/mod.rs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/.config/awesome/quarrel/native/src/net/mod.rs b/.config/awesome/quarrel/native/src/net/mod.rs new file mode 100644 index 0000000..c9d617c --- /dev/null +++ b/.config/awesome/quarrel/native/src/net/mod.rs @@ -0,0 +1,113 @@ +// This is an attempt to port the iwgetid and iwlib code + +mod wireless; +use std::{ + ffi::{ + c_char, + c_int, + c_uchar, + c_void, + }, + mem::size_of, + os::fd::RawFd, + str, +}; + +use mlua::prelude::*; +use nix::{ + ioctl_read_bad, + libc::IF_NAMESIZE, + sys::socket::{ + socket as open_socket, + AddressFamily, + SockFlag, + SockType, + }, + unistd::close +}; +use wireless::{ + IfConf, + IfConfData, + IwPoint, + IwReq, + IwReqData, + IwReqName, + IW_ESSID_MAX_SIZE, + SIOCGIFCONF, + SIOCGIWESSID, +}; + +ioctl_read_bad!(ioctl_get_interfaces, SIOCGIFCONF, IfConf); +ioctl_read_bad!(ioctl_get_essid, SIOCGIWESSID, IwReq); + +pub fn get_first_essid(_: &Lua, _: ()) -> LuaResult<String> { + type Buffer = [c_char; 1024]; + let mut buffer: Buffer = [0; 1024]; + + let mut if_conf = IfConf { + ifc_len: size_of::<Buffer>() as c_int, + data: IfConfData { + ifc_buf: buffer.as_mut_ptr(), + }, + }; + + let mut if_req; + let socket = get_first_socket().map_err(LuaError::external)?; + + unsafe { + ioctl_get_interfaces(socket, &mut if_conf).map_err(LuaError::external)?; + if_req = if_conf.data.ifc_req; + } + + for _ in 0..if_conf.ifc_len / size_of::<IfConf>() as c_int { + if let Ok(essid) = get_essid(socket, unsafe { *if_req }.ifr_name) { + close(socket).map_err(LuaError::external)?; + return Ok(essid); + }; + + unsafe { if_req = if_req.add(1) }; + } + + close(socket).map_err(LuaError::external)?; + Err(LuaError::external("couldn't find any valid interfaces")) +} + +fn get_essid(socket: RawFd, if_name: [c_char; IF_NAMESIZE]) -> LuaResult<String> { + let mut essid: [c_uchar; (IW_ESSID_MAX_SIZE + 1) as usize] = + [0; (IW_ESSID_MAX_SIZE + 1) as usize]; + let mut wrq = IwReq { + ifr_ifrn: IwReqName { ifrn_name: if_name }, + u: IwReqData { + essid: IwPoint { + pointer: essid.as_mut_ptr().cast::<c_void>(), + length: IW_ESSID_MAX_SIZE + 1, + flags: 0, + }, + }, + }; + + unsafe { + ioctl_get_essid(socket, &mut wrq).map_err(LuaError::external)?; + } + + Ok(str::from_utf8(essid.as_slice()) + .map_err(LuaError::external)? + .to_owned()) +} + +fn get_first_socket() -> LuaResult<RawFd> { + let families = [ + AddressFamily::Inet, + AddressFamily::Ipx, + AddressFamily::Ax25, + AddressFamily::AppleTalk, + ]; + + for family in families { + if let Ok(socket) = open_socket(family, SockType::Datagram, SockFlag::empty(), None) { + return Ok(socket); + } + } + + Err(LuaError::external("couldn't get a valid kernel socket")) +} |