// 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, }; 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 { type Buffer = [c_char; 1024]; let mut buffer: Buffer = [0; 1024]; let mut if_conf = IfConf { ifc_len: size_of::() 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; } #[allow(clippy::cast_possible_truncation)] for _ in 0..if_conf.ifc_len / size_of::() 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 { 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::(), length: IW_ESSID_MAX_SIZE + 1, flags: 0, }, }, }; unsafe { ioctl_get_essid(socket, &mut wrq).map_err(LuaError::external)?; } String::from_utf8(essid.to_vec()).map_err(LuaError::external) } fn get_first_socket() -> LuaResult { 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")) }