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. zookeeper分布式部署方案

    版本:http://apache.fayea.com/zookeeper/zookeeper-3.4.8/环境:debian 7/8说明:最低配置3台步骤:1.下载zookeeper-3.4.8并解压 ...

  2. EBS库存(INV)模块常用表

     select * from org_organization_definitions库存组织 select * from mtl_parameters组织参数 select * from mtl ...

  3. 14 fragment传值

    两个fragment传值 方式一 布局文件代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and ...

  4. androidstudio各版本下载地址

    文件夹如下,含android studio多个版本的下载地址:http://pan.baidu.com/s/1ntmdCPN 目前有以下版本: 0.5.2: windows 0.5.4: linux ...

  5. android PakageManagerService启动流程分析

    PakageManagerService的启动流程图 1.PakageManagerService概述 PakageManagerService是android系统中一个核心的服务,它负责系统中Pac ...

  6. 【Android 应用开发】 Android 相关代码规范 更新中 ...

    . 简介 : Android 常用的代码结构, 包括包的规范, 测试用例规范, 数据库模块常用编写规范; 参考 : 之前写的一篇博客 [Android 应用开发] Application 使用分析 ; ...

  7. Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(三)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面看一下CatSprite中最复杂的moveToward方法, ...

  8. Android的DataBinding原理介绍

    Activity在inflate layout时,通过DataBindingUtil来生成绑定,从代码看,是遍历contentView得到View数组对象,然后通过数据绑定library生成对应的Bi ...

  9. 02_Weblogic课程之安装篇:RedHat下JDK安装,RedHat下Weblogic安装,目录结构,环境变量设置

     1  Weblogic的安装方式有三种: 一.GUI方式安装    (java –jar wls1035_generic.jar [-mode=gui])这是默认的 二.Console方式安装  ...

  10. 分布式进阶(五)之JSVC配置

    应用场景:在linux系统上进行项目开发,在部署java项目时,常用方法就是写一个shell脚本,但当服务器重启了,经常会忘了启动shell脚本了.所以我们需要把自己的应用变成linux的服务,当服务 ...