确定网络接口是无线还是有线的

14

我有一个程序,它有两个独立的部分:当网络接口是无线局域网时,应执行其中一个部分;当网络接口是有线局域网连接时,应执行另一个部分。如何在我的程序中判断这一点?我应该使用哪个函数来获取这些信息?


如果有多个网络接口同时被使用,会怎样呢? - unwind
代码中的无线部分将针对无线设备执行,有线部分将针对有线设备并行执行。 - deinocheirus
4个回答

11
如果您的设备名称是NETDEVICE,那么检查/sys/class/net/NETDEVICE/wireless目录是否存在是您可以使用的条件。这是一种仅适用于Linux的方法,并且它假定/sys已经挂载,这几乎总是正常情况。使用此方法比处理ioctl()更容易,特别是在脚本中。

8
您可以使用命令行中的iwconfig命令:
$ iwconfig
lo        no wireless extensions.
eth0      no wireless extensions.

如果你需要从C语言中使用它,如@opaque的链接所述,获取源码或使用strace查看需要使用哪些ioctls():

ioctl(3, SIOCGIWNAME, 0x7fff82c0d040)   = -1 EOPNOTSUPP (Operation not supported)
ioctl(3, SIOCGIFFLAGS, {ifr_name="lo", ifr_flags=IFF_UP|IFF_LOOPBACK|IFF_RUNNING}) = 0
write(2, "lo        no wireless extensions"..., 35lo        no wireless extensions.

) = 35
ioctl(3, SIOCGIWNAME, 0x7fff82c0d040)   = -1 EOPNOTSUPP (Operation not supported)
ioctl(3, SIOCGIFFLAGS, {ifr_name="eth0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
write(2, "eth0      no wireless extensions"..., 35eth0      no wireless extensions.

) = 35

请参考SIOCGIWNAME使用说明

#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
* Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...

嗯...抱歉,我在这里还很新。我可以选择你和opaque的答案作为“正确答案”吗? - deinocheirus
很遗憾不是这样的 ;) 你可以给它们都点赞,但你应该接受最好回答你问题的那个。这是你的决定 :) - Andreas Fester

8
您可以调用ioctl(fd, SIOCGIWNAME)来返回无线扩展协议版本,该协议仅适用于无线接口。
int check_wireless(const char* ifname, char* protocol) {
  int sock = -1;
  struct iwreq pwrq;
  memset(&pwrq, 0, sizeof(pwrq));
  strncpy(pwrq.ifr_name, ifname, IFNAMSIZ);

  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    return 0;
  }

  if (ioctl(sock, SIOCGIWNAME, &pwrq) != -1) {
    if (protocol) strncpy(protocol, pwrq.u.name, IFNAMSIZ);
    close(sock);
    return 1;
  }

  close(sock);
  return 0;
}

完整的示例请参见:https://gist.github.com/edufelipe/6108057

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接