用c/c++实现linux下检测网络接口状态

时间:2022-08-28 15:20:07
       要写个检测网络接口链接状态的东西,又不喜欢不断的ping别的地址,也不想调用其他命令行工具来做这个,于是在google了n多内容未果之后,搜刮到个检测工具的源代码。

以下代码在fedora 9 / CentOS 5.2下调试通过:)

#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <errno.h>
#include <net/if.h>

struct ethtool_value 
{
    __uint32_t cmd;
    __uint32_t data;
};

/*return 1:has cable;   return 0:no cable*/
int detect_eth_cable(char *ifname)   
{
    struct ethtool_value edata;
    struct ifreq ifr;
    int fd = -1, err = 0;

    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, ifname);

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
        //perror("Cannot get control socket");
        return -1;
     }
    edata.cmd = 0x0000000A;
    ifr.ifr_data = (caddr_t)&edata;
    err = ioctl(fd, 0x8946, &ifr);
    if (err == 0) {
        fprintf(stdout, "Link detected: %s\n", edata.data ? "yes":"no");
    } else if (errno != EOPNOTSUPP) {
        perror("Cannot get link status");
     }
    return(edata.data==1 ? 1:0);
}

int main(int argc, char**argv)
{
    detect_eth_cable("p1p1");
    return 0;
}

其他代码:

int get_netportstatus(const char *interface) {
  char cmd[1024];
  char *tt;
  FILE *fp;
  int devflag;
  devflag=get_netflag(interface);
  if (devflag==DEV_DOWN) {
    sprintf(cmd,"ifconfig %s up",interface);
    system(cmd);
  }
  sprintf(cmd,"ethtool %s | grep \"Link detected\" > /tmp/eth.temp",interface);
  system(cmd);
  if (devflag==DEV_DOWN) {
    sprintf(cmd,"ifconfig %s down",interface);
    system(cmd);
  }
  fp=fopen("/tmp/eth.temp","r");
  if (fp==NULL) {
    system("rm -rf /tmp/eth.temp");
    return -1;
  }
  fgets(cmd,1024,fp);
  fclose(fp);
  system("rm -rf /tmp/eth.temp");
  tt=strstr(cmd,"no");
  if (tt!=NULL) return LINK_DOWN;
  tt=strstr(cmd,"yes");
  if (tt!=NULL) return LINK_UP;
  return -1;
}
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <errno.h>
#include <net/if.h>


struct ethtool_value {
        __uint32_t      cmd;
        __uint32_t      data;
};


int main(int , char* [])
{
    struct ethtool_value edata;
    int fd = -1, err = 0;
    struct ifreq ifr;


        memset(&ifr, 0, sizeof(ifr));
        strcpy(ifr.ifr_name, "eth0");
        fd = socket(AF_INET, SOCK_DGRAM, 0);
        if (fd < 0) {
                perror("Cannot get control socket");
                return 70;
        }


        edata.cmd = 0x0000000a;
        ifr.ifr_data = (caddr_t)&edata;
        err = ioctl(fd, 0x8946, &ifr);
        if (err == 0) {
                fprintf(stdout, "Link detected: %s\n",
                        edata.data ? "yes":"no");
        } else if (errno != EOPNOTSUPP) {
                perror("Cannot get link status");
        }
   return 0;
}
#include <net if.h="">  // IFF_RUNNING

//如果网卡已脸上网线,返回0,否则返回-1.
int check_nic(char *nic)
{
    struct ifreq ifr;
    int skfd = socket(AF_INET, SOCK_DGRAM, 0);

    strcpy(ifr.ifr_name, nic_name);
    if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
    {
        return -1;
    }
    if(ifr.ifr_flags & IFF_RUNNING)
        return 0;  // 网卡已插上网线
    else return -1;
}
</net>