9

I need the test case for Ethernet in Linux using C code to check eth0. If eth0 is down, we enable the net then check if up and the test is passed.

Armali
  • 18,255
  • 14
  • 57
  • 171
RAM812
  • 113
  • 2
  • 4
  • 9

5 Answers5

13

To check if the link is up, try something like this. It works without root privileges.

#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"));
}

If IFF_UP is set, it means interface is up (see ifup). If IFF_RUNNING is set then interface is plugged. I also tried using the ethtool ioctl call, but it failed when the gid was not root. But just for the log:

...
#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
  • 7,360
  • 1
  • 41
  • 46
  • @TrueY: One question, assuming I just want to get the status of the link what is the difference between getting it via ETHTOOL_GLINK vs SIOCGIFFLAGS? Does `ethtool_value.data == 1` implies `IFF_UP` and `IFF_RUNNING`. I have asked a detailed question on this at http://stackoverflow.com/questions/33039485/siocethtool-vs-siocgmiiphy-vs-siocgifflags. Please let me know your thoughts on it – Vivek Maran Oct 10 '15 at 20:45
  • @Vivek It was quite long time ago, but I think that if edata.data == 1 then interface is UP and RUNNING. – TrueY Oct 11 '15 at 21:09
  • Can I use the same in virtual environment? How can I set interface down in virtual environment? I am running test program which checks IFF_RUNNING flag at every 500 milliseconds. I am not receiving interface down, it always finds IFF_RUNNING flag set. Need help in this matter. – Brijesh Valera Sep 27 '19 at 07:11
3

The network interfaces can be seen in sysfs: /sys/class/net/eth[x]. There you can check the link, interface status, and more.

Yann Ramin
  • 32,895
  • 3
  • 59
  • 82
2

You may want to take advantage of libudev to get around in /sys:

http://www.signal11.us/oss/udev/
jim mcnamara
  • 16,005
  • 2
  • 34
  • 51
1

I simply check if an Ip address is assigned to the network card.

You can use something like this to check if lan is up in the given network card (say eth0) :

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

This should simply return 0 or 1 based on whether or not an ip address is assigned to the nic.

Also you may use Yann Ramin's method to list out all the nic's & perform the check.


I missed out noticing you are looking for a c code. Maybe adding a tag would be good.

Either ways, I think you can look at the same file (ifconfig) manually in c by reading it for an ip.

loxxy
  • 12,990
  • 2
  • 25
  • 56
1

As this question is somewhat important, I'll add another answer despite its extreme age. You can read the contents of /sys/class/net/eth0/operstate which will simply contain the string "up\n" or "down\n".

Subsentient
  • 554
  • 3
  • 12