3

为了避免依赖无线工具,我想使用 ioctl 直接从设备获取 essid,在 C 中这不是问题,但在 Ruby 中则完全不同。

问题是来自wireless.h的结构,它被用作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 */
};

指针部分必须是内存区域的有效地址,后跟以字节为单位的长度,然后是标志字段。我尝试使用 Array#pack 和 bit-struct gem,但还没有找到解决方案。

有没有办法绕过这个内存指针问题?

4

2 回答 2

4

我终于让它工作了,解决方案是以这种方式使用 pack 的 'p' 参数:

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
于 2009-09-23T09:32:48.317 回答
1

当然,只需将您自己的 Ruby 友好接口定义为 ioctl 的包装器(用 C 语言)。我确实看到了 Ruby 中默认 ioctl 的问题。我想ios.ioctl主要用于ioctl“写”电话。

于 2009-09-18T22:26:28.553 回答