C语言实现linux网卡检测改进版

 更新时间:2018年06月29日 10:44:23   作者:handyhuang  
这篇文章主要为大家详细介绍了C语言实现linux网卡检测的改进版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

 C语言+shell 实现linux网卡状态检测  和 C语言实现linux网卡连接检测 2文的方法各有缺陷,比如有些系统执行ifconfig需要root权限,要不就不支持ioctl(fd, SIOCGMIIPHY, &ifr)这样的操作。以下给出了C语言实现linux网卡连接检测 的改进版实现与C语言+shell 实现linux网卡状态检测 同样的功能。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
 
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/mii.h>
#include <linux/sockios.h>
#include <errno.h>
 
#include <ifaddrs.h>
#include <arpa/inet.h> 
 
#include <linux/ethtool.h>
 
int cshell_netlink_status(char *if_name)
{
 char  buffer[BUFSIZ];
 char  cmd[100];
 FILE  *read_fp;
 int    chars_read;
 int    ret =0;
 
 memset( buffer, 0, BUFSIZ );
 memset( cmd, 0, 100 );
 sprintf(cmd, "ifconfig -a | grep %s",if_name);
 read_fp = popen(cmd, "r");
 if ( read_fp != NULL )
 {
 chars_read = fread(buffer, sizeof(char), BUFSIZ-1, read_fp);
 pclose(read_fp);
 
 if (chars_read > 0)
 {
  ret = 1;
 }
 else
 {
  fprintf(stderr, "DEVICE_NONE\r\n");
  return 0;
 }
 }
 
 if(ret == 1)
 {
 memset( buffer, 0, BUFSIZ );
 memset( cmd, 0, 100 );
 sprintf(cmd, "ifconfig |grep %s",if_name);
 read_fp = popen(cmd, "r");
 if ( read_fp != NULL )
 {
  chars_read = fread(buffer, sizeof(char), BUFSIZ-1, read_fp);
  pclose(read_fp);
 
  if (chars_read > 0)
  {
  ret = 2;
  }
  else
  {
  fprintf(stderr, "DEVICE_DOWN\r\n");
  return 1;
  }
 }
 }
 
 if(ret == 2)
 {
 memset( buffer, 0, BUFSIZ );
 memset( cmd, 0, 100 );
 sprintf(cmd, "ifconfig %s | grep RUNNING | awk '{print $3}'",if_name);
 read_fp = popen(cmd, "r");
 if ( read_fp != NULL )
 {
   chars_read = fread(buffer, sizeof(char), BUFSIZ-1, read_fp);
   pclose(read_fp);
  
   if (chars_read > 0)
   {
  fprintf(stderr, "DEVICE_LINKED\r\n");
  return 3;
   }
   else
   {
  fprintf(stderr, "DEVICE_UNPLUGGED\r\n");
  return 2;
   }
 }
 }
 
 return -1;
}
 
 
int c_netlink_status(const char *if_name )
{
 int fd = -1; 
 struct ifreq ifr; 
 
 struct ifconf ifc; 
 struct ifreq ifrs_buf[100]; 
 int if_number =0;
 int i;
 
 
 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 {
 fprintf(stderr, "%s: socket error [%d] %s\r\n",if_name, errno, strerror(errno));
 close(fd);
 return -1; 
 }
 
 ifc.ifc_len = sizeof(ifrs_buf); 
 ifc.ifc_buf = (caddr_t)ifrs_buf; 
 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) <0) 
 {
 fprintf(stderr, "%s: ioctl SIOCGIFCONF error [%d] %s\r\n",if_name, errno, strerror(errno));
 close(fd);
 return -1; 
 }
 
 if_number = ifc.ifc_len / sizeof(struct ifreq);
 for(i=0; i< if_number; i++)
 {
 if(strcmp(if_name,ifrs_buf[i].ifr_name ) == 0)
 {
  break;
 }
 }
 
 if(i >= if_number)
 {
 close(fd);
 fprintf(stderr, "DEVICE_NONE\r\n");
 return 0;
 }
 
 bzero(&ifr, sizeof(ifr));
 strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1); 
 ifr.ifr_name[IFNAMSIZ-1] = 0; 
 if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) <0) 
 {
 fprintf(stderr, "%s: ioctl SIOCGIFFLAGS error [%d] %s\r\n",if_name, errno, strerror(errno));
 close(fd);
 return -1; 
 }
#if 1 
 if(!(ifr.ifr_flags & IFF_UP))
 {
 close(fd);
 fprintf(stderr, "DEVICE_DOWN\r\n");
 return 1;
 }
 
 if(!(ifr.ifr_flags & IFF_RUNNING))
 {
 close(fd);
 fprintf(stderr, "DEVICE_UNPLUGGED\r\n");
 return 2 ;
 }
 
 fprintf(stderr, "DEVICE_LINKED\r\n");
 return 3;
 
#else
{
 struct ethtool_value edata;
 if(!(ifr.ifr_flags & IFF_UP) || !(ifr.ifr_flags & IFF_RUNNING))
 {
 close(fd);
 fprintf(stderr, "%s: DOWN\r\n",if_name);
 return 1;
 }
 edata.cmd = ETHTOOL_GLINK;
 edata.data = 0;
 ifr.ifr_data = (char *) &edata;
 if(ioctl( fd, SIOCETHTOOL, &ifr ) < 0)
 {
 fprintf(stderr, "%s: ioctl SIOCETHTOOL error [%d] %s\r\n",if_name, errno, strerror(errno));
 close(fd);
 return -1; 
 }
 
 if(edata.data == 0)
 {
 fprintf(stderr, "DEVICE_UNPLUGGED\r\n");
 return 2; 
 }
 else
 {
 fprintf(stderr, "DEVICE_LINKED\r\n");
 return 3; 
 }
}
#endif
}
 
int main(int argc, char* argv[])
{
 int i=0;
 if(argc != 2)
 {
 fprintf(stderr, "usage: %s <ethname>\r\n", argv[0]);
 return -1;
 }
 
 i = cshell_netlink_status(argv[1]);
 
 printf( "cshell_netlink_status if_status = %d\n", i );
 
 i = c_netlink_status(argv[1]);
 printf( "c_netlink_status if_status = %d\n", i );
 
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C语言自动生成enum值和名字映射代码

    C语言自动生成enum值和名字映射代码

    这篇文章主要介绍了C语言自动生成enum值和名字映射代码的相关资料,需要的朋友可以参考下
    2015-12-12
  • C++中自定义sleep、条件变量sleep实例

    C++中自定义sleep、条件变量sleep实例

    这篇文章主要介绍了C++中自定义sleep、条件变量sleep实例,本文直接给出实例代码并讲解了功能作用和使用方法,需要的朋友可以参考下
    2015-03-03
  • C++如何通过ostringstream实现任意类型转string

    C++如何通过ostringstream实现任意类型转string

    再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
    2013-09-09
  • opencv实现多张图像拼接

    opencv实现多张图像拼接

    这篇文章主要为大家详细介绍了opencv实现多张图像拼接功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • 深入理解atoi()与itoa()函数的用法

    深入理解atoi()与itoa()函数的用法

    本篇文章是对atoi()与itoa()函数的用法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言中的各种文件读写方法小结

    C语言中的各种文件读写方法小结

    这篇文章主要介绍了C语言中的各种文件读写方法小结,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-07-07
  • 详解C语言实现空间索引四叉树

    详解C语言实现空间索引四叉树

    本文主要介绍了用C语言实现四叉树,对算法感兴趣的同学,可以参考下,并且试验一下。
    2021-05-05
  • C++中的多态详谈

    C++中的多态详谈

    多态通俗来说就是多种形态,本文通过实例代码给大家介绍C++中的多态定义及实现,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-05-05
  • C++设计模式之命令模式

    C++设计模式之命令模式

    这篇文章主要介绍了C++设计模式之命令模式,本文讲解了什么是命令模式、命令模式的使用场合等内容,并给出了一个代码实例,需要的朋友可以参考下
    2014-10-10
  • 介绍C语言中tolower函数的实例

    介绍C语言中tolower函数的实例

    这篇文章主要介绍了介绍C语言中tolower函数的实例,本文列出了该函数的头文件,功能说明等,以及如何使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07

最新评论