博文

目前显示的是标签为“netlink”的博文

初试Netlink之unicast

        在之前已经了解了好几种内核态与用户态之间数据的交换方法,但那些方法都是单向的(即单工),其关系是一对一的,而Netlink Socket则是一种用于内核与用户空间之间传递信息的特殊IPC,在用户进程中,其以标准的Socket API为内核和用户之间提供了全双工的通信通道,在内核模块中则提供了一类特殊的API。相比TCP/IP socket所使用的AF_INET地址族,Netlink socket则使用AF_NETLINK地址族,每一个Netlink Socket都在Kernel的include/uapi/linux/netlink.h(linux-3.11.0-rc4,关于Netlink部分相关文档,如无注明均以该版本为基准)中定义了相应的protocol type。         在Linux  Kernel中,以模块形式去创建Netlink Socket时需要涉及到如下相关的API及数据结构:         1.创建Socket            在include/linux/netlink.h文件中,有如下的定义:            /* optional Netlink kernel configuration parameters */            struct netlink_kernel_cfg {                    unsigned int    groups;   ...

通过Netlink检测USB设备的插拔

    在Android的Vold里面可以了解到,其检测USB的插拔是通过Netlink机制来实现的,那我们也来尝试下如何在Linux下写个程序检测USB设备的插拔,下面我们将使用Netlink的NETLINK_KOBJECT_UEVENT类型套接字与Kernel进行通信,然后使用setsocketopt()来利用该套接字,再使用select()并发检测相应的套接写是否可操作,具体的代码实现 如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/socket.h> #include <linux/netlink.h> #define UEVENT_BUFFER_SIZE 2048 int main(void) {     struct sockaddr_nl client;     struct timeval tv;     int fd, rcvlen, ret;     fd_set fds;     int buffersize = 1024;     fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);     memset(&client, 0, sizeof(client));     client.nl_family = AF_NETLINK;     client.nl_pid = getpid();     client.nl_groups = 1; /* receive broadcast message*/     setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffe...

通过Netlink检测网线插拔

  最近有个需求需要检测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 <st...