美文网首页
通过Netlink检测网线插拔

通过Netlink检测网线插拔

作者: 网路元素 | 来源:发表于2019-11-02 07:44 被阅读0次

    最近有个需求需要检测RJ45网卡的网线有没有接上,而最近正在了解Netlink相关资料,刚好也看下通过Netlink可以进行检测,故在此做下粗略笔记:

    1.首先要创建一个Netlink Socket,在用户层使用如下参数来调用socket()函数:

       fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 

       上面这个函数第一个参数必须是AF_NETLINK或PF_NETLINK,这两个标志在Linux下是一样的,第二个参数可以是SOCK_RAW或SOCK_DGRAM(对应用到TCP或UDP协议),而最后一个参数NETLINK_ROUTE为“路由守护进程”,用于接收来自内核的路由通知事件。

    2.将上面创建的Socket绑定

addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK; //指定接收路由多播组消息
bind(fd, (struct sockaddr*)&addr, sizeof(addr));

       上面将创建的socket与相应的协议族和组进行绑定,接下来通过读fd这个socket来获得相应的消息数据struct nlmsghdr,再对该结构体数据进行判断来获得网线是接上或是拔掉,相应的源码如下:

#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

相关文章

  • 通过Netlink检测网线插拔

    最近有个需求需要检测RJ45网卡的网线有没有接上,而最近正在了解Netlink相关资料,刚好也看下通过Netli...

  • 通过Netlink检测USB设备的插拔

    在Android的Vold里面可以了解到,其检测USB的插拔是通过Netlink机制来实现的,那我们也来尝试下...

  • android_8.1 hdmi设备热插拔事件

    平时我们对hdmi等设备插拔,只要硬件支持设备热插拔检测,android都有代码检测到,热插拔函数为: frame...

  • kernel netlink

    kernel netlink so we can use netlink fuzz general, rout, ...

  • 计算机网络 - 4

    转发设备 信号从网卡发出进入网线后,就通过网线进入了网络,网线是双绞线(拧在一起防止噪声干扰),通过网线传入转发设...

  • Linux libnetlink 编程

    netlink,rtnetlink,libnetlink 三者之间的关系是: netlink 是Linux内核和用...

  • 2019-12-25突然断网

    这几天在公司加班,今天奇葩了,20:30左右,发现网络没有了。网线重新插拔一下,电脑也重启了,没用,确实是网络不好...

  • Mac,音频设备插拔检测

    做Mac的音频采集播放,总免不了要处理过程中音频设备插拔的问题。而Mac并不像IOS一样有好用的插拔通知可用,只能...

  • C# socket在断开网线后不能重连

    进度:经过以下代码(服务端)的测试,在客户端关机或者服务端软件的关闭后重新打开,网络可以自动连接,但是如果插拔网线...

  • netfilter.org "libmnl" 项目(transl

    什么是libmnl? libmnl是面向Netlink开发人员的简约用户空间库。 在解析,验证,构建Netlink...

网友评论

      本文标题:通过Netlink检测网线插拔

      本文链接:https://www.haomeiwen.com/subject/ehcryctx.html