Getting essid via ioctl in ruby

China☆狼群 提交于 2019-12-07 15:22:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!