Linux中与内核通信的Netlink机制Word文档下载推荐.docx

上传人:b****4 文档编号:18024661 上传时间:2022-12-13 格式:DOCX 页数:23 大小:23.74KB
下载 相关 举报
Linux中与内核通信的Netlink机制Word文档下载推荐.docx_第1页
第1页 / 共23页
Linux中与内核通信的Netlink机制Word文档下载推荐.docx_第2页
第2页 / 共23页
Linux中与内核通信的Netlink机制Word文档下载推荐.docx_第3页
第3页 / 共23页
Linux中与内核通信的Netlink机制Word文档下载推荐.docx_第4页
第4页 / 共23页
Linux中与内核通信的Netlink机制Word文档下载推荐.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

Linux中与内核通信的Netlink机制Word文档下载推荐.docx

《Linux中与内核通信的Netlink机制Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Linux中与内核通信的Netlink机制Word文档下载推荐.docx(23页珍藏版)》请在冰豆网上搜索。

Linux中与内核通信的Netlink机制Word文档下载推荐.docx

只有当内核空间中的input()函数返回时,用户调用的sendmsg()函数才会返回。

对于这种情况,可以定义一个内核线程专门负责消息接收,而函数input的工作只是唤醒该内核线程,这样sendmsg将很快返回。

(这里网上的的说明)不过在查看Linux2.6.37版本的内核时并没有发现这种处理过程,一般都是按下面的方法进行处理。

这里注册的netlink协议为NETLINK_XFRM。

nlsk=netlink_kernel_create(net,NETLINK_XFRM,XFRMNLGRP_MAX,

xfrm_netlink_rcv,NULL,THIS_MODULE);

staticvoidxfrm_netlink_rcv(structsk_buff*skb)

{

mutex_lock(&

xfrm_cfg_mutex);

netlink_rcv_skb(skb,&

xfrm_user_rcv_msg);

mutex_unlock(&

}

在netlink_rcv_skb()函数中进行接收处理。

intnetlink_broadcast(structsock*ssk,structsk_buff*skb,u32pid,

u32group,gfp_tallocation)

前面的三个参数与netlink_unicast相同,参数group为接收消息的多播组,该参数的每一个位代表一个多播组,因此如果发送给多个多播组,就把该参数设置为多个多播组组ID的位或。

参数allocation为内核内存分配类型,一般地为GFP_ATOMIC或GFP_KERNEL,GFP_ATOMIC用于原子的上下文(即不可以睡眠),而GFP_KERNEL用于非原子上下文。

NETLINK_CB(skb).pid=0;

NETLINK_CB(skb).dst_pid=0;

NETLINK_CB(skb).dst_group=1;

字段pid表示消息发送者进程ID,也即源地址,对于内核,它为0,dst_pid表示消息接收者进程ID,也即目标地址,如果目标为组或内核,它设置为0,否则dst_group表示目标组地址,如果它目标为某一进程或内核,dst_group应当设置为0。

下面是参考网上使用netlink写的和内核通信的两个程序,一个是用户空间,一个是内核空间。

内核空间:

#include<

linux/init.h>

linux/module.h>

linux/timer.h>

linux/time.h>

linux/types.h>

net/sock.h>

net/netlink.h>

#defineNETLINK_TEST25

#defineMAX_MSGSIZE1024

intstringlength(char*s);

voidsendnlmsg(char*message);

intpid;

interr;

structsock*nl_sk=NULL;

intflag=0;

voidsendnlmsg(char*message)

structsk_buff*skb_1;

structnlmsghdr*nlh;

intlen=NLMSG_SPACE(MAX_MSGSIZE);

intslen=0;

if(!

message||!

nl_sk)

{

return;

}

skb_1=alloc_skb(len,GFP_KERNEL);

skb_1)

printk(KERN_ERR"

my_net_link:

alloc_skb_1error\n"

);

slen=stringlength(message);

nlh=nlmsg_put(skb_1,0,0,0,MAX_MSGSIZE,0);

NETLINK_CB(skb_1).pid=0;

NETLINK_CB(skb_1).dst_group=0;

message[slen]='

\0'

;

memcpy(NLMSG_DATA(nlh),message,slen+1);

printk("

sendmessage'

%s'

.\n"

(char*)NLMSG_DATA(nlh));

netlink_unicast(nl_sk,skb_1,pid,MSG_DONTWAIT);

intstringlength(char*s)

for(;

*s;

s++){

slen++;

returnslen;

voidnl_data_ready(structsk_buff*__skb)

structsk_buff*skb;

charstr[100];

structcompletioncmpl;

inti=10;

skb=skb_get(__skb);

if(skb->

len>

=NLMSG_SPACE(0))

nlh=nlmsg_hdr(skb);

memcpy(str,NLMSG_DATA(nlh),sizeof(str));

Messagereceived:

%s\n"

str);

pid=nlh->

nlmsg_pid;

while(i--)

init_completion(&

cmpl);

wait_for_completion_timeout(&

cmpl,3*HZ);

sendnlmsg("

Iamfromkernel!

"

flag=1;

kfree_skb(skb);

//Initializenetlink

intnetlink_init(void)

nl_sk=netlink_kernel_create(&

init_net,NETLINK_TEST,1,

nl_data_ready,NULL,THIS_MODULE);

nl_sk){

createnetlinksocketerror.\n"

return1;

my_net_link_3:

createnetlinksocketok.\n"

return0;

staticvoidnetlink_exit(void)

if(nl_sk!

=NULL){

sock_release(nl_sk->

sk_socket);

selfmoduleexited\n"

module_init(netlink_init);

module_exit(netlink_exit);

MODULE_AUTHOR("

frankzfz"

MODULE_LICENSE("

GPL"

下面是用户空间的程序:

sys/stat.h>

unistd.h>

stdio.h>

stdlib.h>

sys/socket.h>

sys/types.h>

string.h>

asm/types.h>

linux/netlink.h>

linux/socket.h>

errno.h>

#defineMAX_PAYLOAD1024//maximumpayloadsize

intmain(intargc,char*argv[])

intstate;

structsockaddr_nlsrc_addr,dest_addr;

structnlmsghdr*nlh=NULL;

structioveciov;

structmsghdrmsg;

intsock_fd,retval;

intstate_smg=0;

//Createasocket

sock_fd=socket(AF_NETLINK,SOCK_RAW,NETLINK_TEST);

if(sock_fd==-1){

printf("

errorgettingsocket:

%s"

strerror(errno));

return-1;

//Topreparebinding

memset(&

msg,0,sizeof(msg));

src_addr,0,sizeof(src_addr));

src_addr.nl_family=AF_NETLINK;

src_addr.nl_pid=getpid();

//selfpid

src_addr.nl_groups=0;

//multicast

retval=bind(sock_fd,(structsockaddr*)&

src_addr,sizeof(src_addr));

if(retval<

0){

bindfailed:

close(sock_fd);

//Topreparerecvmsg

nlh=(structnlmsghdr*)malloc(NLMSG_SPACE(MAX_PAYLOAD));

nlh){

mallocnlmsghdrerror!

\n"

dest_addr,0,sizeof(dest_addr));

dest_addr.nl_family=AF_NETLINK;

dest_addr.nl_pid=0;

dest_addr.nl_groups=0;

nlh->

nlmsg_len=NLMSG_SPACE(MAX_PAYLOAD);

nlmsg_pid=getpid();

nlmsg_flags=0;

strcpy(NLMSG_DATA(nlh),"

Helloyou!

iov.iov_base=(void*)nlh;

iov.iov_len=NLMSG_SPACE(MAX_PAYLOAD);

//iov.iov_len=nlh->

nlmsg_len;

msg,0,sizeof(msg));

msg.msg_name=(void*)&

dest_addr;

msg.msg_namelen=sizeof(dest_addr);

msg.msg_iov=&

iov;

msg.msg_iovlen=1;

state_smg\n"

state_smg=sendmsg(sock_fd,&

msg,0);

if(state_smg==-1)

geterrorsendmsg=%s\n"

strerror(errno));

memset(nlh,0,NLMSG_SPACE(MAX_PAYLOAD));

waitingreceived!

//Readmessagefromkernel

while

(1){

Inwhilerecvmsg\n"

state=recvmsg(sock_fd,&

msg,0);

if(state<

0)

state<

1"

Inwhile\n"

Receivedmessage:

%s\n"

(char*)NLMSG_DATA(nlh));

下面是Makefile文件:

obj-m:

=netlink_k.o

KERNELBUILD:

=/lib/modules/`uname-r`/build

default:

@echo"

BUILEKmod"

@make-C$(KERNELBUILD)M=$(shellpwd)modules

gcc-onetlink_2netlink_2.c

clean:

CLEANkmod"

@rm-rf*.o

@rm-rf.depend.*.cmd*.ko*.mod.c.tmp_versions*.symvers.*.d

其中,netlink_k.c为内核的空间的程序。

先运行内核代码netlink_k.ko,也就是在执行完makefile文件后,会生成一个netlink_k.ko文件,可以使用下面的命令进行安装,insmodnetlink_k.ko,使用lsmod查看,当安装成功后,然后,执行./netlink用户空间程序,可以在另一个终端下执行dmesg命令,查看内核通信的情况。

这里netlink程序向内核空间发送一个helloyou!

内核返回给一个Iamfromkernel!

在这里使用了一个定时器,也就是每3秒中发送一次Iamfromkernel!

只有内核把10个字符串全部发送完毕后,用户空间的sendmsg()才会返回,也就是在用户空间的netlink才会输出内核空间发送过来的数据,这里只有一个简单的程序,并没有什么实际的意义,因为,正如前面所说的一般情况下不会在回调函数中处理太多的东西,以免sendmsg()函数返回不及时。

下面是使用dmesg命令输出的信息。

[873791.498039]my_net_link_3:

createnetlinksocketok.

[873810.263676]Messagereceived:

Hello

[873813.260848]my_net_link_4:

'

.

[873816.260821]my_net_link_4:

[873819.260860]my_net_link_4:

[873822.260762]my_net_link_4:

[873825.260883]my_net_link_4:

[873828.260669]my_net_link_4:

[873831.260714]my_net_link_4:

[873834.260683]my_net_link_4:

[873837.260666]my_net_link_4:

[873840.260632]my_net_link_4:

2.6.24以上内核中netlink使用方法

测试环境:

2.6.28

Netlink在2.6内核的不同版本中发生了很大变化,具体请参考(注意其中的版本号不一定确切):

0.综述

以下程序基本流程如下:

运行netlink内核模块;

运行用户态程序,向内核发送连接消息,通知内核自身进程id;

内核接收用户消息,记录其进程id;

内核向用户进程id发送netlink消息;

用户接收内核发送的netlink消息。

1.内核部分

1.1相关的数据结构变量:

44//---------Thesearefornetlink---------//

45#defineNETLINK_REALNET26

46structsock*g_nl_sk=NULL;

48structsockaddr_nlsrc_addr,dest_addr;

50structioveciov;

52intpid;

53structmsghdrmsg;

55//-----------------------------------------//

44//---------Thesearefornetlink---------//

45#defineNETLINK_REALNET26

46structsock*g_nl_sk=NULL;

48structsockaddr_nlsrc_addr,dest_addr;

50structioveciov;

52intpid;

53structmsghdrmsg;

55//-----------------------------------------//

45#defineNETLINK_REALNET26

定义协议族。

该变量在ne

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1