#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned char u8;
/* 获取MII phy的地址 然后读取phy寄存器的值*/
int detect_mii(int skfd, char *ifname)
{
struct ifreq ifr;
u16 *data, mii_val;
unsigned phy_id;
/* Get the vitals from the interface. */
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0)
{
fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname, strerror(errno));
(void) close(skfd);
return 2;
}
data = (u16 *)(&ifr.ifr_data);
phy_id = data[0];
data[1] = 1;
if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0)
{
fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, strerror(errno));
return 2;
}
mii_val = data[3];
return(((mii_val & 0x0016) == 0x0004) ? 0 : 1);
}
int detect_ethtool(int skfd, char *ifname)
{
struct ifreq ifr; /* ifreq里包含了接口的所有信息,比如接口名,地址等等 */
struct ethtool_value edata;
memset(&ifr, 0, sizeof(ifr));
edata.cmd = ETHTOOL_GLINK;
/* 设置要查询的网卡接口名称 */
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1);
ifr.ifr_data = (char *) &edata;
if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1)
{
printf("ETHTOOL_GLINK failed: %s\n", strerror(errno));
return 2;
}
return (edata.data ? 0 : 1);
}
int CheckNet()
{
int skfd = -1;
/* 如果这里所填的名字没有对应的phy(比如phy2),则会报错No such device */
char *ifname = "eth0";
int retval;
/* Open a socket. */
if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 )
{
printf("socket error\n");
exit(-1);
}
/* 这里使用两种方式来获取网卡的状态 */
retval = detect_ethtool(skfd, ifname); /* 使用SIOCETHTOOL方式获取 */
if (retval == 2)
{
retval = detect_mii(skfd, ifname); /*使用SIOCGMIIPHY方式获取,即先获取指定phy的地址,然后读指定的寄存器*/
}
close(skfd);
return retval;
}
//int main(int argc, char **argv)
int phyOperate(void* arg)
{
int ret = -1,retold = -1;
while(1)
{
ret = CheckNet();
/*如果状态发生变化才打印*/
if(ret != retold)
{
retold = ret;
if (ret == 2)
printf("Could not determine status\n");
if (ret == 1)
printf("Link down %s pid = %d\n",(char*)arg,getpid());
if (ret == 0)
printf("Link up %s pid = %d\n",(char*)arg,getpid());
}
}
}
/*多个线程检测网卡状态*/
int main()
{
int i = 0;
pthread_t thread1,thread2,thread3,thread4;
pthread_create(&thread1,NULL,phyOperate,"thread1");
pthread_create(&thread2,NULL,phyOperate,"thread2");
pthread_create(&thread3,NULL,phyOperate,"thread3");
//pthread_create(&thread4,NULL,phyOperate,"thread4");
/*不加下面的话线程会结束*/
pthread_join(thread1,"thread1");
pthread_join(thread2,"thread2");
pthread_join(thread3,"thread3");
//pthread_join(thread4,"thread4");
}
通过socket获取网卡状态
猜你喜欢
转载自blog.csdn.net/weixin_38239856/article/details/83000334
今日推荐
周排行