ruby – 指向IOCTL调用缓冲区的指针
发布时间:2020-12-17 02:13:51 所属栏目:百科 来源:网络整理
导读:我正在使用 Ruby和bit-struct在测试设置中配置我的网络接口.这适用于大多数IOCTL调用,但我无法弄清楚如何调用SIOCGIFCONF 这是一个例子: 如果我想获取接口的MAC地址,我会写这样的东西: class LinuxIfreqMacAddr BitStruct char :name,128 unsigned :type,1
我正在使用
Ruby和bit-struct在测试设置中配置我的网络接口.这适用于大多数IOCTL调用,但我无法弄清楚如何调用SIOCGIFCONF
这是一个例子: 如果我想获取接口的MAC地址,我会写这样的东西: class LinuxIfreqMacAddr < BitStruct char :name,128 unsigned :type,16,:endian => :native hex_octets :macaddr,48 pad :padding,64 end ifr = LinuxIfreqMacAddr.new ifr.name = "eth0" s.ioctl(SIOCGIFHWADDR,ifr) # s is a socket puts ifr.macaddr 这很好,并将打印eth0的MAC地址.但是“struct ifconf”(与SIOCGIFCONF一起使用)的签名需要传递缓冲区. 这是签名: struct ifconf { int ifc_len; char __user *ifcu_buf; }; 我如何从ruby调用SIOCGIFCONF ioctl命令,缓冲区为4096字节? 解决方法
使用
Array#pack的“P”说明符存储指向a的指针
缓冲: require 'socket' sock = UDPSocket.new ifreqs = ' ' * 4096 ifconf = [ifreqs.size,ifreqs].pack("l!P") SIOCGIFCONF = 0x8912 sock.ioctl(SIOCGIFCONF,ifconf) data_size = ifconf.unpack('l!').first p data_size # => 120 这是如何工作的 创建ioctl将存储接口信息数组的缓冲区: ifreqs = ' ' * 4096 现在创建缓冲区以传递给ioctl调用.缓冲区将是一个 struct ifconf { int ifc_len; /* size of buffer */ union { char *ifc_buf; /* buffer address */ struct ifreq *ifc_req; /* array of structures */ }; }; 我们使用Array#pack来做到这一点: ifconf = [ifreqs.size,ifreqs].pack("l!P") 格式说明符分解为: >“我!” – 签名长的平台原生大小.这编码ifreqs.size. 现在我们可以打电话: SIOCGIFCONF = 0x8912 sock.ioctl(SIOCGIFCONF,ifconf) SIOCGIFCONF调用修改ifconf缓冲区,将ifc_len更新为 data_size = ifconf.unpack('l!').first p data_size # => 120 将存储在ifreqs中的数据解码为一个练习读者. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |