Linux的netlink机制是非常好的Linux内核与应用层进行双向交互数据的方式。其常用的单播方式可以实现内核为服务端,应用层为客户端的通信方式。如果需要实现应用层为服务端,内核为客户端的通信方式,则需要使用组播。这种场景一般是应用层守护进程需要实现获取内核的某些模块的状态信息。

内核中已经定义好的组有:

#define NETLINK_ROUTE           0       /* Routing/device hook                          */
#define NETLINK_W1 1 /* 1-wire subsystem */
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
#define NETLINK_FIREWALL 3 /* Firewalling hook */
#define NETLINK_INET_DIAG 4 /* INET socket monitoring */
#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
#define NETLINK_XFRM 6 /* ipsec */
#define NETLINK_SELINUX 7 /* SELinux event notifications */
#define NETLINK_ISCSI 8 /* Open-iSCSI */
#define NETLINK_AUDIT 9 /* auditing */
#define NETLINK_FIB_LOOKUP 10
#define NETLINK_CONNECTOR 11
#define NETLINK_NETFILTER 12 /* netfilter subsystem */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
#define NETLINK_GENERIC 16

内核代码:

 #include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <net/sock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
#include <linux/delay.h> #define NETLINK_USER 29 //User defined group, consistent in both kernel prog and user prog
#define MYGRP 2 //User defined group, consistent in both kernel prog and user prog struct sock *nl_sk = NULL; static void send_to_user(void); static void send_to_user(void)
{
struct sk_buff *skb_out;
struct nlmsghdr *nlh;
int msg_size;
char msg[] = "Hello from kernel";
int res; printk(KERN_INFO "Entering: %s\n", __FUNCTION__);
msg_size = strlen(msg);
printk(KERN_INFO "msg_size: %d\n", msg_size);
//msg[msg_size - 1] = '\0';
skb_out = nlmsg_new(msg_size, ); if (!skb_out) {
printk(KERN_ERR "Failed to allocate new skb\n");
return;
}
nlh = nlmsg_put(skb_out, , , NLMSG_DONE, msg_size, );
//NETLINK_CB(skb_out).dst_group = 1; /* Multicast to group 1, 1<<0 */
strncpy(nlmsg_data(nlh), msg, msg_size); res = nlmsg_multicast(nl_sk, skb_out, , MYGRP, );
if (res < ) {
printk(KERN_INFO "Error while sending bak to user, err id: %d\n", res);
}
} static int __init
hello_init(void) { struct netlink_kernel_cfg cfg = {
.groups = MYGRP,
};
printk("Entering: %s\n", __FUNCTION__);
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
if (!nl_sk) {
printk(KERN_ALERT "Error creating socket.\n");
return -;
} msleep();
send_to_user(); return ;
} static void __exit
hello_exit(void) { printk(KERN_INFO "exiting hello module\n");
netlink_kernel_release(nl_sk);
} module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

应用层代码:

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<linux/netlink.h>
#include<sys/types.h>
#include<unistd.h> #define MYPROTO 29 //User defined group, consistent in both kernel prog and user prog
#define MYMGRP 2 //User defined group, consistent in both kernel prog and user prog int open_netlink()
{
int sock = socket(AF_NETLINK,SOCK_RAW,MYPROTO);
struct sockaddr_nl addr; memset((void *)&addr, , sizeof(addr)); if (sock<)
return sock;
addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid();
addr.nl_groups = MYMGRP;
if (bind(sock,(struct sockaddr *)&addr,sizeof(addr))<)
return -;
return sock;
} int read_event(int sock)
{
struct sockaddr_nl nladdr;
struct msghdr msg;
struct iovec iov[];
struct nlmsghdr nlh;
char buffer[];
int ret;
iov[].iov_base = (void *)&nlh;
iov[].iov_len = sizeof(nlh);
iov[].iov_base = (void *)buffer;
iov[].iov_len = sizeof(buffer);
msg.msg_name = (void *)&(nladdr);
msg.msg_namelen = sizeof(nladdr);
msg.msg_iov = iov;
msg.msg_iovlen = sizeof(iov)/sizeof(iov[]);
ret=recvmsg(sock, &msg, );
if (ret<) {
return ret;
}
printf("Received message payload: %s\n", NLMSG_DATA(&nlh));
char *a = NLMSG_DATA(&nlh);
int i;
printf("Recv Data:\n");
for(i = ; i < ; i++) {
printf("%c", a[i]);
}
printf("\n");
} int main(int argc, char *argv[])
{
int nls = open_netlink();
if (nls<) {
err(,"netlink");
} while ()
read_event(nls);
return ;
}

其中 协议类型与组号 内核要与应用层保持一致,且内核模块要先运行。

netlink组播的使用的更多相关文章

  1. Linux IPC socket 广播,组播

    getsockopt()/setsockopt() //获得sockfd指向的socket的属性 int getsockopt(int sockfd, int level, int optname, ...

  2. IPv4组播通信原理

    2011-05-08 21:21:14 标签:组播 vin_do,vin_do学习笔记,笔记 休闲 职场 摘自网络,感谢原作者 摘要: 本文试图成为学习TCP/IP网络组播技术的入门材料.文中介绍了组 ...

  3. UDP及其组播,接收发送封装

    1.Receiver public class Receiver { public delegate void HeartBeat(byte[] data); public event HeartBe ...

  4. ffmpeg无法接收组播流问题处理

    问题:ffmpeg无法对IP组播进行处理,表现如下 [root@os01 /]# ffprobe udp://225.0.0.2:9000 ffprobe version Copyright (c) ...

  5. 组播(Multicast)传输

    组播(Multicast)传输: 在发送者和每一接收者之间实现点对多点网络连接. 如果一台发送者同时给多个的接收者传输相同的数据,也只需复制一份的相同数据包.它提高了数据传送效率.减少了骨干网络出现拥 ...

  6. dell n2000 组播抑制

    http://en.community.dell.com/support-forums/network-switches/f/866/t/19677497 http://en.community.de ...

  7. Ztack学习笔记(6)-广播组播点播

    Zigbee网络中进行数据通信主要有三种类型:单播.组播.广播.那这三种方式如何设置呢,在哪里设置呢, 一. 广播 当应用程序需要将数据包发送给网络的每一个设备时,使用这种模式.广播的短地址有三种 0 ...

  8. [转]IP_ADD_MEMBERSHIP : 组播错误 的解决方法:

    [转]IP_ADD_MEMBERSHIP : 组播错误 的解决方法: http://www.cnitblog.com/dvb-dvb/archive/2012/10/15/aa.html by def ...

  9. [转载] ACE 组播校验和出错问题解决

    源地址:http://yuanmuqiuyu2000.blog.sohu.com/140904942.html 使用ACE框架写了个组播简单的测试工具,但是测试过程中,总是发现udp校验和出错的信息. ...

随机推荐

  1. 指令汇B新闻客户端开发(五) ShareSdk的使用

    ShareSdk是一个分享按钮的开源框架,我们首先可以去mob的官网下载这个控件.mob官网,然后找到sdk下载那一栏, 下载下来之后点击这个.jar文件就会有一个弹窗,填写自己的应用包名和要哪些分享 ...

  2. iOS注册远程推送消息证书后提示此证书签发者无效的解决办法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们在编写关于远程推送消息的App时需要注册一个相关的证书,我 ...

  3. 4.2、Android Studio压缩你的代码和资源

    为了让你的APK文件尽可能的小,你需要在构建的时候开启压缩来移除无用的代码和资源. 代码压缩可在ProGuard中使用,可以检测和清除无用的类,变量,方法和属性,甚至包括你引用的库.ProGuard同 ...

  4. antlr v4 使用指南连载3——g4文件概览

    g4文件概览        在深入介绍之前,有必要先给大家了解一下g4文件的结构,以便对如何编写语法规则文件有个全局的认识,我想这是大有禆益的.因为这样我们就可以很清晰地知道需要的东西写在哪里,或者哪 ...

  5. jar包执行报ClassNotFoundException

    使用Eclipse打包jar包,指定了main class. java -jar mongoCluster.jar 但是运行的时候报ClassNotFoundException NoClassDefF ...

  6. 【Unity Shaders】Vertex & Fragment Shader入门

    写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判 ...

  7. 如何解决RK3168或者RK系列MASKROM的问题

    不知道使用RK芯片的小伙伴有没有遇到我这样的问题,在用Android-Tool下载相应 IMG的时候,正常情况下,按电源键和音量+键应该出现loader下载模式,但是却出现MASKROM的字样,以前不 ...

  8. Java-IO之InputStreamReader和OutputStreamWriter

    InputStreamReader和OutputStreamWriter是字节流通向字符流的桥梁.它使用指定的差染色体读写字节并将其解码为字符.InputStreamReader的作用是将字节输入流转 ...

  9. centos7安装jdk,tomcat,msyql(MariaDB)

    操作系统版本 CentOS Linux release 7.2.1511 (Core) 安装jdk 下载jdk-8u66-linux-x64.rpm上传到linux上 先改用户权限 然后 rpm -i ...

  10. matlab函数interp2及其c++代码

    最近将一个matlab程序转为c++,途中遇到interp2这个家伙,我是左查右查,发现网上没有人总结这个玩意,于是我来初探一下,还是别有洞天的,嘿嘿. 1.关于interp2 Vq = interp ...