c - 使用 wireless.h 的 C 语言中的无线 ESSID 和信号强度

标签 c wireless ioctl

我目前有一个应用程序使用 popen(nmcli...) 获取 essid 和信号强度,我正尝试使用 wireless.h 和 ioctl 切换到纯 C。获取 ESSID 很容易,但是尝试通过 SIOCGIWSTATS 获取强度/质量总是给我一个“不支持的操作”错误。任何人都可以发现我做错了什么,或者可能只是我的无线驱动程序实际上不支持 SIOCGIWSTATS?

请忽略全局变量的使用,它只是我调试当前问题时的临时变量。

谢谢,

海顿。



    #include <string.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <ifaddrs.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <linux/wireless.h>
    #include <stdlib.h>
    #include <errno.h>

    char ifname[IFNAMSIZ];
    char essid[IW_ESSID_MAX_SIZE+1];
    struct iwreq wrq;
    struct iw_statistics *iwstats;
    int sock;


    int findWifi() {
      struct ifaddrs *ifaddr, *ifa;

      if (getifaddrs(&ifaddr) == -1) {
        perror("Error getting interface addresses");
        return -1;
      }

      for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        strncpy(wrq.ifr_name, ifa->ifa_name, IFNAMSIZ);

        if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
          perror("Error opening INET socket");
        }

        if (ioctl(sock, SIOCGIWNAME, &wrq) == 0) {
          printf("IF: %s\n", wrq.ifr_name);
          strcpy(ifname, wrq.ifr_name);
          freeifaddrs(ifaddr);
          return sock;
        }
      }
      freeifaddrs(ifaddr);
      return 0;
    }

    int wifiInfo() {
      wrq.u.essid.pointer = essid;
      if (ioctl(sock, SIOCGIWESSID, &wrq) == -1) {
        perror("Can't open socket to obtain essid");
        return(-1);
      }

      printf("ESSID is %s\n", wrq.u.essid.pointer);

      memset(&iwstats, 0, sizeof(iwstats));

      wrq.u.data.pointer = (caddr_t) &iwstats;
      wrq.u.data.length = sizeof(&iwstats);
      wrq.u.data.flags = 1;

      // ERROR HERE...
      if (ioctl(sock, SIOCGIWSTATS, &wrq) == -1) {
        perror("Can't open socket to obtain iwstats");
        return(-1);
      }

      return(0);
    }

    int main(int argc, char const *argv[]) {
      findWifi();
      wifiInfo();
      return 0;
    }

最佳答案

Can anyone spot what I've done wrong, or maybe it's just my wireless driver that doesn't actually support SIOCGIWSTATS?

您的代码看起来不错或至少非常接近,尽管这一行需要仔细检查:

wrq.u.data.pointer = (caddr_t) &iwstats;

这不会在 Ubuntu 16.04 上编译,因为 caddr_t未声明。即使在添加 <linux/types.h> and <sys/types.h> 之后也会发生这种情况.

谷歌搜索似乎表明这个 caddr_t是特定于 BSD 的,建议您不要使用它:

What is the significance of caddr_t and when is it used?


对于问题的第二部分,您可以检查 Wifi 驱动程序是否真的支持 SIOCGIWSTATS通过使用 iwconfig 等常用工具.

关于c - 使用 wireless.h 的 C 语言中的无线 ESSID 和信号强度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59087739/

相关文章:

c - 通过多个函数传递一个变量,没有得到想要的结果

对 libcap (pcap) 和无线感到困惑

android - 支持通过 Wifi、蓝牙或 USB 传输 Android 和 PC 数据的框架?

linux-kernel - 如何让 VirtualBox 或 VMware(或任何其他虚拟化软件)使用 native 访客网络驱动程序?

C Linux ioctl TCGETS 和 TCSETS errno 25

c - 如何检查某个类型是否已在 C 编译器中定义?

c - 用C语言将结构写入文件

c - 访问字符串元素困惑

networking - UDP(数据报)套接字的 FIONREAD 返回什么?

c - 获取以太网端口的 ioctl 文件描述符