1.首先要创建一个Netlink Socket,在用户层使用如下参数来调用socket()函数:
1fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
上面这个函数第一个参数必须是AF_NETLINK或PF_NETLINK,这两个标志在Linux下是一样的,第二个参数可以是SOCK_RAW或SOCK_DGRAM(对应用到TCP或UDP协议),而最后一个参数NETLINK_ROUTE为“路由守护进程”,用于接收来自内核的路由通知事件。
2.将上面创建的Socket绑定
123addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK;
//指定接收路由多播组消息
bind(fd, (
struct
sockaddr*)&addr,
sizeof
(addr));
上面将创建的socket与相应的协议族和组进行绑定,接下来通过读fd这个socket来获得相应的消息数据struct nlmsghdr,再对该结构体数据进行判断来获得网线是接上或是拔掉,相应的源码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253#include <sys/types.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <string.h>
#define BUFLEN 20480
int
main(
int
argc,
char
*argv[])
{
int
fd, retval;
char
buf[BUFLEN] = {0};
int
len = BUFLEN;
struct
sockaddr_nl addr;
struct
nlmsghdr *nh;
struct
ifinfomsg *ifinfo;
struct
rtattr *attr;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len,
sizeof
(len));
memset
(&addr, 0,
sizeof
(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK;
bind(fd, (
struct
sockaddr*)&addr,
sizeof
(addr));
while
((retval = read(fd, buf, BUFLEN)) > 0)
{
for
(nh = (
struct
nlmsghdr *)buf; NLMSG_OK(nh, retval); nh = NLMSG_NEXT(nh, retval))
{
if
(nh->nlmsg_type == NLMSG_DONE)
break
;
else
if
(nh->nlmsg_type == NLMSG_ERROR)
return
;
else
if
(nh->nlmsg_type != RTM_NEWLINK)
continue
;
ifinfo = NLMSG_DATA(nh);
printf
(
"%u: %s"
, ifinfo->ifi_index, (ifinfo->ifi_flags & IFF_LOWER_UP) ?
"up"
:
"down"
);
attr = (
struct
rtattr*)(((
char
*)nh) + NLMSG_SPACE(
sizeof
(*ifinfo)));
len = nh->nlmsg_len - NLMSG_SPACE(
sizeof
(*ifinfo));
for
(; RTA_OK(attr, len); attr = RTA_NEXT(attr, len))
{
if
(attr->rta_type == IFLA_IFNAME)
{
printf
(
" %s"
, (
char
*)RTA_DATA(attr));
break
;
}
}
printf
(
"\n"
);
}
}
return
0;
}
将上面的代码保存成文件rj45_pulg_check.c,然后执行命令gcc -o rj45_pulg_check rj45_pulg_check.c进行编译,生成rj45_pulg_check文件,执行该文件后再插拔网线,有如下内容输出:
2: down eth0
2: up eth0
注意:上述操作须在网卡驱动加载后进行,并且使用ifconfig里能看到该网卡信息(如没有则执行ifconfig eth0 up),实际上就相当于有没有分配到IP地址(即网络有没有通路)的判断。当我们开关WiFi时也可以检测到。
参考网址:
http://blog.csdn.net/sourthstar/article/details/7975999
http://blog.chinaunix.net/uid-317451-id-92692.html
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2302
- 用户1336
- 访客10980672
每日一句
If you want to achieve greatness, stop asking for permission.
如果你想获得伟大,别再请求许可。
如果你想获得伟大,别再请求许可。
排名前5的开源在线机器学习
Android自定义蜂窝view
Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手
Java中的(耦合)控制反转
OpenGL读取帧缓存数据
首发:Thinkpad T550黑苹果10.13.4安装教程
反编译修改class文件变量
IntelliJ IDEA2018~2019.1激活码-注册码
p2p通信,打洞技术,穿越NAT的实现(附NAT环境检测工具)
【黑苹果安装】——如何在windows下操作EFI分区
Could not resolve io.flutter 解决方法
MPAndroidChart标记控件MarkerView的使用方法
imencode和imdecode使用
新会员