问题
To avoid relying on the wireless tools I want to get the essid directly from the device with ioctl, in C this wouldn't be a problem, but in Ruby it's quite different.
The problem is following struct from wireless.h that is used as input/reply of 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 */
};
The pointer part must be a valid address of a memory area, followed by the length in bytes, followed by a flag field. I tried with Array#pack and the bit-struct gem, but haven't found a solution yet.
Is there a way to bypass this memory pointer problem?
回答1:
I finally got it working, the solution was to use the 'p' argument of pack in this way:
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
回答2:
Sure, just define your own Ruby-friendly interface as a wrapper (in C) around ioctl. I do see the problem with the default ioctl in Ruby. I guess ios.ioctl
is mostly intended for ioctl
"write" calls.
来源:https://stackoverflow.com/questions/1446806/getting-essid-via-ioctl-in-ruby