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. storm消费kafka实现实时计算

    大致架构 * 每个应用实例部署一个日志agent * agent实时将日志发送到kafka * storm实时计算日志 * storm计算结果保存到hbase storm消费kafka 创建实时计算项 ...

  2. JQuery之动画与特效

    显示与隐藏 show(spped,[callback])与hide(spped,[callback]) speed可选填slow.normal.fast,对应的速度分别为600ms.400ms.200 ...

  3. UNIX网络编程——名字与地址转换(gethostbyname,gethostbyaddr,getservbyname,getservbyport,getaddrinfo,getnameinfo函数)

    名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IPv4地址之间进行转换.getservbyname和getservbyport在服务器名字和端口号之 ...

  4. 一个简单程序快速入门JDBC

    首先创建jdbc的库,再在这个库里面创建一张users表. drop database if exists jdbc; create database if not exists jdbc; use ...

  5. android 减少图片出现oom错误

    在做Android图片程序的时候,由于图片比较多,很有很的机会出现OOM的机会,根据网上的资料做了些总结,期待能够减少OOM出现的机会. 1.使用底层的方法来替代使用java层的方法 尽量不要使用se ...

  6. 软件测试进阶(一)A/B测试终极指南

    A/B测试终极指南 A/B测试不是一个时髦名词.现在很多有经验的营销和设计工作者用它来获得访客行为信息,来提高转换率.然而,A/B测试与SEO不同的是,人们都不太知道如何进行网站分析和可用性分析.他们 ...

  7. msm8974 camera driver添加新摄像头kernel hal修改

    添加一款新摄像头流程 1添加sensor kernel driver, 主要实现上电.rst.pwd.mclk等power setting,sensor prob & sensor  i2c ...

  8. javascript语法之number对象和Math对象

    这两个对象很简单,一个例子就能掌握用法. 一:number对象. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...

  9. C语言之任意进制的转换

    我们都知道转换进制是一个让人比较头疼的事情,下面我的代码不是最好的,也就仅仅是一个思路而已,至少我认为使用栈来进行进制转换是比较合适的一种方法,好了,不多叙述了. #include<stdio. ...

  10. (三十四)NavigationController初步

    为了了解底层,首先不基于UIWindow而基于UIWindow来创建App. 由于Xcode6没有以前的基于UIWindow的空项目,所以选择SingleView,然后删除storyboard,移除B ...