如何在Linux中检查以太网?

9

我需要使用C代码在Linux中编写以检查eth0的以太网测试用例。如果eth0处于离线状态,我们会启用网络,然后检查是否已上线,测试将被视为通过。

5个回答

13

要检查链接是否正常,可以尝试像这样的操作。它不需要 root 权限。

#include <stdio.h>        // printf
#include <string.h>       // strncpy
//#include <sys/socket.h> // AF_INET
#include <sys/ioctl.h>    // SIOCGIFFLAGS
#include <errno.h>        // errno
#include <netinet/in.h>   // IPPROTO_IP
#include <net/if.h>       // IFF_*, ifreq

#define ERROR(fmt, ...) do { printf(fmt, __VA_ARGS__); return -1; } while(0)

int CheckLink(char *ifname) {
    int state = -1;
    int socId = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (socId < 0) ERROR("Socket failed. Errno = %d\n", errno);

    struct ifreq if_req;
    (void) strncpy(if_req.ifr_name, ifname, sizeof(if_req.ifr_name));
    int rv = ioctl(socId, SIOCGIFFLAGS, &if_req);
    close(socId);

    if ( rv == -1) ERROR("Ioctl failed. Errno = %d\n", errno);

    return (if_req.ifr_flags & IFF_UP) && (if_req.ifr_flags & IFF_RUNNING);
}

int main() {
    printf("%d\n", CheckLink("eth0"));
}

如果设置了IFF_UP,表示接口已启用(参见ifup)。如果设置了IFF_RUNNING,则表示接口已连接。

我还尝试使用ethtool ioctl调用,但当gid不是root时失败了。但仅供记录:

...
#include <asm/types.h>     // __u32
#include <linux/ethtool.h> // ETHTOOL_GLINK
#include <linux/sockios.h> // SIOCETHTOOL
...
int CheckLink(char *ifname) {
    ...
    struct ifreq if_req;
    (void) strncpy( if_req.ifr_name, ifname, sizeof(if_req.ifr_name) );

    struct ethtool_value edata;
    edata.cmd = ETHTOOL_GLINK;
    if_req.ifr_data = (char*) &edata;

    int rv = ioctl(socId, SIOCETHTOOL, &if_req);
    ...

    return !!edata.data;
}

@TrueY:一个问题,假设我只想获取链接的状态,通过ETHTOOL_GLINK和SIOCGIFFLAGS获取有什么区别?ethtool_value.data == 1是否意味着IFF_UPIFF_RUNNING。我在http://stackoverflow.com/questions/33039485/siocethtool-vs-siocgmiiphy-vs-siocgifflags上提出了一个详细的问题,请告诉我您的想法。 - Vivek Maran
@Vivek,这是很久以前的事了,但我认为如果 edata.data == 1,则接口已经启动并运行。 - TrueY
我能在虚拟环境中使用相同的吗?我如何在虚拟环境中设置接口下降?我正在运行测试程序,每500毫秒检查IFF_RUNNING标志。我没有收到接口关闭的消息,它总是找到IFF_RUNNING标志设置。需要在这个问题上得到帮助。 - Brijesh Valera

3

网络接口可以在sysfs中查看:/sys/class/net/eth[x]。您可以在那里检查链接、接口状态等信息。


2

您可能希望利用libudev在/sys中进行操作:

http://www.signal11.us/oss/udev/

1
由于这个问题比较重要,尽管它的年代已久,我还是会添加另一个答案。您可以读取/sys/class/net/eth0/operstate的内容,其中将简单包含字符串"up\n"或"down\n"。

1

我只是检查网络适配器是否分配了IP地址。

您可以使用类似以下代码来检查给定网络适配器(例如 eth0)的局域网是否正常:

/sbin/ifconfig eth0| grep 'inet addr:' | wc -l

这应该根据网卡是否分配了 IP 地址,简单地返回 0 或 1。

此外,您可以使用 Yann Ramin 的方法列出所有网卡并执行检查。


我没有注意到您正在寻找C代码。也许添加一个标签会很好。

无论如何,我认为您可以通过手动读取文件(ifconfig)中的IP地址来使用C语言进行查看。


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