Obtenir l'essentiel via ioctl en rubis
Question
Pour éviter de me fier aux outils sans fil, je souhaite obtenir l’essentiel directement à partir du périphérique avec ioctl. En C, cela ne poserait pas de problème, mais en Ruby, c’est très différent.
Le problème provient de la structure de wireless.h utilisée comme entrée / réponse de ioctl:
.struct iw_point
{
void __user *pointer; /* Pointer to the data (in user space) */
__u16 length; /* number of fields or size in bytes */
__u16 flags; /* Optional params */
};
La partie pointeur doit être une adresse valide d’une zone mémoire, suivie de la longueur en octets, suivie d’un champ de drapeau. J'ai essayé avec Array # pack et le gem bit-struct, mais je n'ai pas encore trouvé de solution.
Existe-t-il un moyen de contourner ce problème de pointeur de mémoire?
La solution
J'ai finalement réussi à le faire fonctionner, la solution consistait à utiliser l'argument 'p' de pack de la manière suivante:
require "socket"
# Copied from wireless.h
SIOCGIWESSID = 0x8B1B
IW_ESSID_MAX_SIZE = 32
iwreq = [ "wlan0", " " * IW_ESSID_MAX_SIZE, IW_ESSID_MAX_SIZE, 0 ].pack("a16pII")
sock = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
sock.ioctl(SIOCGIWESSID, iwreq)
interface, essid, len, flags = iwreq.unpack("a16pII")
puts essid
Autres conseils
Bien sûr, définissez simplement votre propre interface Ruby comme un wrapper (en C) autour de ioctl. Je vois le problème avec l'ioctl par défaut dans Ruby. Je suppose que ios.ioctl
est principalement destiné à ioctl
" write " appels.