linux 内核与用户空间通信之netlink使用方法Word格式.docx

上传人:b****2 文档编号:13304724 上传时间:2022-10-09 格式:DOCX 页数:9 大小:19.30KB
下载 相关 举报
linux 内核与用户空间通信之netlink使用方法Word格式.docx_第1页
第1页 / 共9页
linux 内核与用户空间通信之netlink使用方法Word格式.docx_第2页
第2页 / 共9页
linux 内核与用户空间通信之netlink使用方法Word格式.docx_第3页
第3页 / 共9页
linux 内核与用户空间通信之netlink使用方法Word格式.docx_第4页
第4页 / 共9页
linux 内核与用户空间通信之netlink使用方法Word格式.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

linux 内核与用户空间通信之netlink使用方法Word格式.docx

《linux 内核与用户空间通信之netlink使用方法Word格式.docx》由会员分享,可在线阅读,更多相关《linux 内核与用户空间通信之netlink使用方法Word格式.docx(9页珍藏版)》请在冰豆网上搜索。

linux 内核与用户空间通信之netlink使用方法Word格式.docx

完成绑定,内核空间接收到用户进程ID之后便可以进行通讯。

用户空间进程发送数据使用标准socketAPI中sendmsg()函数完成,使用时需添加structmsghdr消息和nlmsghdr消息头。

一个netlink消息体由nlmsghdr和消息的payload部分组成,输入消息后,内核会进入nlmsghdr指向的缓冲区。

内核空间发送数据使用独立创建的sk_buff缓冲区,Linux定义了如下宏方便对于缓冲区地址的设置,如下所示:

#defineNETLINK_CB(skb)(*(structnetlink_skb_parms*)

参数sk为函数netlink_kernel_create()返回的socket,参数skb存放消息,它的data字段指向要发送的netlink消息结构,而skb的控制块保存了消息的地址信息,前面的宏NETLINK_CB(skb)就用于方便设置该控制块,参数pid为接收消息进程的pid,参数nonblock表示该函数是否为非阻塞,如果为1,该函数将在没有接收缓存可利用时立即返回,而如果为0,该函数在没有接收缓存可利用时睡眠。

内核模块或子系统也可以使用函数netlink_broadcast来发送广播消息:

voidnetlink_broadcast(structsock*sk,structsk_buff*skb,u32pid,u32group,intallocation);

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

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

接收数据时程序需要申请足够大的空间来存储netlink消息头和消息的payload部分。

然后使用标准函数接口recvmsg()来接收netlink消息

4Netlink通信过程

调试平台:

Vmware5.5+FedoraCore10(两台,一台作为host机,一台作为target机)。

调试程序:

分为内核模块和用户空间程序两部分,当内核模块被加载后,运行用户空间程序,由用户空间发起Netlink会话,和内核模块进行数据交换。

被加载的内核模块无法通过外加的调试器进行调试,KGDB提供了一种内核源码级别的调试机制。

Linux内核自2.6.26版本之后在内核中内置了KGDB选项,编译内核时需要选择与之相关的选项,调试时host端需使用带有符号表的vmlinz内核,target端使用gdb调试用户空间的程序。

用户空间程序关键代码如下:

intsend_pck_to_kern(u8op,constu8*data,u16data_len){structuser_data_*pck;

intret;

pck=(structuser_data_*)calloc(1,sizeof(*pck)+data_len);

if(!

pck){printf("

callocin%sfailed!

!

\n"

__FUNCTION__);

return-1;

}pck->

magic_num=MAGIC_NUM_RNQ;

pck->

op=op;

data_len=data_len;

memcpy(pck->

data,data,data_len);

ret=send_to_kern((constu8*)pck,sizeof(*pck)+data_len);

if(ret)printf("

send_to_kernin%sfailed!

free(pck);

returnret?

-1:

0;

}staticvoidrecv_from_nl(){charbuf[1000];

intlen;

structioveciov={buf,sizeof(buf)};

structsockaddr_nlsa;

structmsghdrmsg;

structnlmsghdr*nh;

memset(msg.msg_name=(void*)msg.msg_namelen=sizeof(sa);

msg.msg_iov=msg.msg_iovlen=1;

//len=recvmsg(nl_sock,len=recvmsg(nl_sock,for(nh=(structnlmsghdr*)buf;

NLMSG_OK(nh,len);

nh=NLMSG_NEXT(nh,len)){//Theendofmultipartmessage.if(nh->

nlmsg_type==NLMSG_DONE){puts("

nh->

nlmsg_type==NLMSG_DONE"

);

return;

}if(nh->

nlmsg_type==NLMSG_ERROR){//Dosomeerrorhandling.puts("

nlmsg_type==NLMSG_ERROR"

}#if1puts("

Datareceivedfromkernel:

"

hex_dump((u8*)NLMSG_DATA(nh),NLMSG_PAYLOAD(nh,0));

#endif}}

内核模块需要防止资源抢占,保证Netlink资源互斥占有,内核模块部分关键代码如下:

staTIcvoidnl_rcv(structsk_buff*skb){mutex_lock(netlink_rcv_skb(skb,mutex_unlock(}staTIcintnl_send_msg(constu8*data,intdata_len){structnlmsghdr*rep;

u8*res;

structsk_buff*skb;

if(g_pid0){printk("

Datatobesendtouserspace:

hex_dump((void*)data,data_len);

}rep=__nlmsg_put(skb,g_pid,0,NLMSG_NOOP,data_len,0);

res=nlmsg_data(rep);

memcpy(res,data,data_len);

netlink_unicast(g_nl_sk,skb,g_pid,MSG_DONTWAIT);

return0;

}staTIcintnl_rcv_msg(structsk_buff*skb,structnlmsghdr*nlh){constu8res_data[]="

Hello,user"

;

size_tdata_len;

u8*buf;

structuser_data_*pck;

structuser_req*req,*match=NULL;

g_pid=NETLINK_CB(skb).pid;

buf=(u8*)NLMSG_DATA(nlh);

data_len=nlmsg_len(nlh);

if(data_lenmagic_num!

=MAGIC_NUM_RNQ){printk("

Magicnumbernotmatched!

}if(g_debug_level>

0){printk("

Datafromuserspace:

hex_dump(buf,data_len);

}req=user_reqs;

while(req->

op){if(req->

op==pck->

op){match=req;

break;

}req++;

}if(match){match->

handler(buf,data_len);

}nl_send_msg(res_data,sizeof(res_data));

}

5.其他相关说明

 

Netlink是一种特殊的socket,它是Linux所特有的,类似于BSD中的AF_ROUTE但又远比它的功能强大,目前在最新的Linux内核(2.6.14)中使用netlink进行应用与内核通信的应用很多,包括:

路由daemon(NETLINK_ROUTE),1-wire子系统(NETLINK_W1),用户态socket协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket监视(NETLINK_INET_DIAG),netfilter日志(NETLINK_NFLOG),ipsec安全策略(NETLINK_XFRM),SELinux事件通知(NETLINK_SELINUX),iSCSI子系统(NETLINK_ISCSI),进程审计(NETLINK_AUDIT),转发信息表查询(NETLINK_FIB_LOOKUP),netlinkconnector(NETLINK_CONNECTOR),netfilter子系统(NETLINK_NETFILTER),IPv6防火墙(NETLINK_IP6_FW),DECnet路由信息(NETLINK_DNRTMSG),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用netlink(NETLINK_GENERIC)。

Netlink是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的socketAPI就可以使用netlink提供的强大功能,内核态需要使用专门的内核API来使用netlink。

Netlink相对于系统调用,ioctl以及/proc文件系统而言具有以下优点:

1,为了使用netlink,用户仅需要在include/linux/netlink.h中增加一个新类型的netlink协议定义即可,如#defineNETLINK_MYTEST17然后,内核和用户态应用就可以立

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

当前位置:首页 > 高等教育 > 农学

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

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