失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > shell 判断网线插拔_linux检测网线插拔状态

shell 判断网线插拔_linux检测网线插拔状态

时间:2019-03-24 15:28:19

相关推荐

shell 判断网线插拔_linux检测网线插拔状态

Shell查看网线插拔状态:

使用ifconfig命令,如果含有“RUNNING”,说明网线接入,否则就没有。

例:

ifconfig

ifconfig eth0

ifconfig eth0|grep "RUNNING"

================================================================================================

C编程查看网线插拔状态:

参考网络资料,经整理验证ok.

#include

#include

#include

#include

#include

intnet_detect(char*net_name)

{

intskfd=0;

structifreqifr;

structsockaddr_in*pAddr=NULL;

skfd=socket(AF_INET,SOCK_DGRAM,0);

if(skfd

{

printf("%s:%dOpensocketerror!\n",__FILE__,__LINE__);

return-1;

}

strcpy(ifr.ifr_name,net_name);

if(ioctl(skfd,SIOCGIFFLAGS,&ifr)<0)

{

printf("%s:%dIOCTLerror!\n",__FILE__,__LINE__);

printf("Maybeethernetinferface%sisnotvalid!",ifr.ifr_name);

close(skfd);

return-1;

}

if(ifr.ifr_flags&IFF_RUNNING)

{

printf("%sisrunning:)\n",ifr.ifr_name);

}

else

{

printf("%sisnotrunning:(\n",ifr.ifr_name);

}

if(ioctl(skfd,SIOCGIFADDR,&ifr)<0)

{

printf("SIOCGIFADDRIOCTLerror!\n");

close(skfd);

return-1;

}

pAddr=(structsockaddr_in*)&(ifr.ifr_addr);

printf("ipaddr:[%s]\n",inet_ntoa(pAddr->sin_addr));

if(ioctl(skfd,SIOCGIFHWADDR,&ifr)<0)

{

printf("SIOCGIFHWADDRIOCTLerror!\n");

close(skfd);

return-1;

}

printf("macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",

(unsignedchar)ifr.ifr_hwaddr.sa_data[0],

(unsignedchar)ifr.ifr_hwaddr.sa_data[1],

(unsignedchar)ifr.ifr_hwaddr.sa_data[2],

(unsignedchar)ifr.ifr_hwaddr.sa_data[3],

(unsignedchar)ifr.ifr_hwaddr.sa_data[4],

(unsignedchar)ifr.ifr_hwaddr.sa_data[5]);

close(skfd);

return0;

}

voidmain()

{

net_detect("eth0");

}

参考网络资料:

1、对于基于linux2.4内核的uclinux系统如何实现在应用层监控网线插拔状态?

2、硬件环境:IPS100(ARM7TDMI)

3、实现过程

由于linux下的ifconfig命令就能够实现在应用层监控网线插拔状态,例如当网线连接正常时,使用ifconfigeth0命令,打印的信息中会有RUNNING,而拔掉网线后,再使用ifconfigeth0命令,RUNNING就不见了。所以,实现Linux应用层监控网线插入状态就相当于自己写一个ifconfig函数。

基于这个思路,首先参考ifconfig的源码,可以参考linux自身提供的ifconfig的源码(linux提供的有ifconfig.c函数),也可以在网上查找。首先找到linux自身提供的ifconfig.c函数,既然ifconfig通过RUNNING来判断网络的通断的状况的,首先找到RUNNING的出处,搜索一下发现这句话,

If(ptr->flags&IFF_RUNNIG)

{

Printf(__("RUNNING"));

}

以这个为切入点,层层向上找,分别是被些函数调用,最后我们进入了main函数(这是理所当然的),在这里的到RUNNING→ife_print()→if_pirint()→main().。先看ife_prinf()函数,这里没有和内核通信,这时我们再看if_print()函数,这里刚好有和内核通信的函数,else{

structinterface*ife;

ife=lookup_interface(ifname);

res=do_if_fetch(ife);

if(res>=0)

ife_print(ife);

}

这时需要看到lookup_interface(ifname)和do_if_fetch(ife)的原型,由于头文件很多,我没办法知道这两个函数在那个头文件中,所以干脆在网上找到这两个函数的原型,我们找到了一篇ifconfing源码分析的文章,http://viscar./2574772.html,这里面找到了函数原型,我们看到do_if_fetch()函数里面又调用了if_fetch()函数,太好了,这个函数正是我们所需要的,在这里面有个很重要的函数ioctl(),ioctl用于向设备发送控制和配置命令,驱动程序可以接收ioctl的数据,并返回数据,ioctl的原型为

ioctl(intd,intcmd,......),

d是某个设备的文件描述符,cmd是ioctl的命令,可变参数取决于cmd,是指向变量或结构体的指针。

这里面用到的设备文件描述符skfd=socket(AF_INET,SOCK_DGRAM,0);这是一个套接字,作用是打开一个网络通讯端口,成功的话返回skfd,相当于一个文件描述符。

有了这些之后我们就可以写一个自己的简洁版的ifconfig函数了,现在ubuntu10.04上编写代码,代码里面的ioctl函数这样写ioctl(skfd,SIOCGIFFLAGS,&ifr),其中SIOCGIGGLAGS表示得到socki/o的flags,这时因为,RUNNIGN的条件是ptr->flags&IFF_RUNNING是否为真,代码里面直接体现eth0,函数为strcpy(ifr.ifr_name,“eth0”);完整的代码如下:

(以下代码在ubuntu 10.04下运行通过)

#include"icconst.h"

#include

#include

#include

#include

#include

#include"net_detect.h"

intnet_detect(char*net_name)

{

intskfd=0;

structifreqifr;

skfd=socket(AF_INET,SOCK_DGRAM,0);

if(skfd

{

printf("%s:%dOpensocketerror!\n",__FILE__,__LINE__);

return-1;

}

strcpy(ifr.ifr_name,net_name);

if(ioctl(skfd,SIOCGIFFLAGS,&ifr)<0)

{

printf("%s:%dIOCTLerror!\n",__FILE__,__LINE__);

printf("Maybeethernetinferface%sisnotvalid!",ifr.ifr_name);

close(skfd);

return-1;

}

if(ifr.ifr_flags&IFF_RUNNING)

{

printf("%sisrunning:)\n",ifr.ifr_name);

}

else

{

printf("%sisnotrunning:(\n",ifr.ifr_name);

}

/*****************以下为识别ip地址,mac地址***************************************/

if(ioctl(skfd,SIOCGIFADDR,&ifr)<0)

{

printf("SIOCGIFADDRIOCTLerror!\n");

close(skfd);

return-1;

}

printf("ipaddr:[%s]\n",inet_ntoa(((structsockaddr_in*)&(ifr.ifr_addr))->sin_addr));

if(ioctl(skfd,SIOCGIFHWADDR,&ifr)<0)

{

printf("SIOCGIFHWADDRIOCTLerror!\n");

close(skfd);

return-1;

}

printf("macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n"

(unsignedchar)ifr.ifr_hwaddr.sa_data[0],

(unsignedchar)ifr.ifr_hwaddr.sa_data[1],

(unsignedchar)ifr.ifr_hwaddr.sa_data[2],

(unsignedchar)ifr.ifr_hwaddr.sa_data[3],

(unsignedchar)ifr.ifr_hwaddr.sa_data[4],

(unsignedchar)ifr.ifr_hwaddr.sa_data[5]);

/*************************************************************************************************************************************/

close(skfd);

return0;

}

代码里面的structifreq是一个设备请求的结构体,在中定义,SIOCGIFFLAGS使用了ifreq结构,

在ubuntu10.04环境下编译之后,运行#./a.outeth0即可实现网线插拔的监控。

这时把代码加到uclinux下运行,发现并不能实现ubuntu的效果,这是为什么呢?

初步分析原因,可能是在驱动程序中没有将插拔状态的信息通知内核,所以我们使用ioctl实际上不能获得内核网络设备的状态的信息。我们在《linux设备驱动程序这本书上》看到有两个函数刚好做这件事情:

Voidnetif_carrier_off(structnet_device*dev);

Voidnetif_carrier_on(structnet_device*dev);

当驱动检测到设备没有连接好,可以调用netif_carrier_off通知内核这一事情;当设备再次连接好时,调用netif_carrier_on通知内核现在连接好了。

现在我们将这两个函数分别加到驱动程序中,放到监控网线插拔状态的位置,再在unlinux中插拔网线时,会在串口终端打印出相应的状态信息,这时的状态信息完全是在应用层实现的。

4.参考文档:uclinux内核网络驱动源码和ifconfig的源码

《linux设备驱动程序》

如果觉得《shell 判断网线插拔_linux检测网线插拔状态》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。