【问题标题】:How to differentiate ethernet from the others?如何区分以太网与其他以太网?
【发布时间】:2011-11-12 01:51:31
【问题描述】:

这里的答案中建议Get the IP address of the machine,可以使用getifaddrs() 获取运行程序的机器的IP 地址,效果很好:D:D

但是,在两个不同的系统上运行相同的程序,显示一个

SERVER_ADDRESS lo 127.0.0.1
SERVER_ADDRESS eth0 129.xxx.xxx.xxx
SERVER_ADDRESS virbr0 192.zzz.zzz.1

当另一个显示时

SERVER_ADDRESS lo0 127.0.0.1
SERVER_ADDRESS en0 192.yyy.yyy.yyy

我打算使用strcmp 来区分以太网,但现在我意识到它不能跨系统工作,因为可能会打印出不同的字符串。

是否有检查ifa_name 是否为以太网的功能(或更好的方法)?

【问题讨论】:

  • 短的 ping 时间意味着 localhost ;)
  • ifconfig 表明 localhost 接口具有 LOOPBACK 属性。也许可以以某种方式在 C 中提取这些信息。

标签: c linux networking


【解决方案1】:

要(再次)明确说明这一点:127.0.0.0/255.0.0.0 网络(范围)的所有地址,包括从127.0.0.0127.255.255.255 的地址,都被定义为本地环回地址。发送给此类的数据不会离开本地计算机。

无论如何你已经在使用getifaddrs() live 很容易.. - 只需像这样测试struct ifaddrsIFF_LOOPBACK 返回的结构的成员ifa_flags

#include <sys/types.h>
#include <ifaddrs.h>
#include <net/if.h> /* for IFF_LOOPBACK */

...

struct ifaddrs * pIfAddrs = NULL;

if (!getifaddrs(&pIfAddrs)) {
  /* Test if the first interface is looping back to the local host. */
  int iIsLoopBack = (0 != (pIfAddrs->ifa_flags & IFF_LOOPBACK)); 
  ...
}

...

/* clean up */
if (pIfAddrs) {
  freeifaddrs(pIfAddrs);
  pIfAddrs = NULL;
}

...

【讨论】:

  • 谢谢@alk,我正在寻找这样的东西!是否有讨论不同 IFF_XXX 的手册页?我需要专门识别ethernet,因为它还显示virbr0 192.zzz.zzz.z。恐怕IFF_LOOPBACK不会排除192.zzz.zzz.zzz
  • @sheldon 127.x.y.z 的区别。地址和在互联网上使用的地址和127.x.y.z的区别。与亚历克斯·格雷发布的参考资料中提到的地址不同。 ;-) 让后者按照惯例是私有的,但不是在技术上处理它们的方式,127.x.y.z 在技术上被视为私有,因为它们没有路由到使用它们的主机的外部。因此,需要通过实际测试地址的值来区分 alex gray 引用的地址。仅将 127.x.y.z 地址检测为私有(本地)的接口。
  • 我在这里阅读过kernel.org/doc/man-pages/online/pages/man7/netdevice.7.html,了解不同类型的ifa_flags。您能否指出哪些标志可以识别以太网连接?谢谢!
  • 您可以查看 net-tools 包的源代码,ifconfig 也从中了解如何做到这一点……还有很多其他的东西。我现在也可以这样做,为您提供一些示例,但由于这是一个阳光明媚的星期天,我更喜欢今天去远足...... ;-)
  • 您可以从这里提取原始网络工具源:ftp.de.debian.org/debian/pool/main/n/net-tools/…(在lib/interface.clib/hw.c 中查看),并度过美好而阳光明媚的一天! :-)
【解决方案2】:

您可能遇到的不仅仅是那个问题。例如,有多个 NIC、vLAN、WANS 看起来像 LAN,反之亦然,等等。

什么是已知的? 127.X.X.X 扔掉那个结果,你就得到了非环回。

如果你想知道地址是否是私人地址..you'll then have to go down this road.

【讨论】:

    【解决方案3】:
    /* Output:
    Name: 'eth0' Addr: 'xxx.xxx.xxx.xxx'
    Name: 'eth0:0' Addr: 'xxx.xxx.xxx.xxx'
    */
    
        struct ifaddrs *ifaddr;
        char ip[255];
    
        if (getifaddrs(&ifaddr) == -1)
           {
              //sprintf(ip[0], "%s", strerror(errno));
           }
           else
           {
              struct ifaddrs *ifa;
              int i = 0, family;
              for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
              {
                 if (ifa->ifa_addr == NULL)
                 {
                    continue;
                 }
                 family = ifa->ifa_addr->sa_family;
                 if (family == AF_INET || family == AF_INET6)
                 {
                    if(!(ifa->ifa_flags & IFF_LOOPBACK) && (family == AF_INET) && getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0)
                    {
                       printf("Name: '%s' Addr: '%s'\n", ifa->ifa_name, ip);
                    }
                 }
              }
           }
           freeifaddrs(ifaddr);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多