首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

linux netlink通讯

2012-10-16 
linux netlink通信(1)加入自己的NETLINK通信端口?????在/usr/include/linux/netlink.h?中加入?NETLINK_TES

linux netlink通信

(1)加入自己的NETLINK通信端口

?????在/usr/include/linux/netlink.h?中加入?NETLINK_TEST?20

(2)用户层代码

#include?<stdio.h>

#include?<unistd.h>

#include?<sys/types.h>

#include?<sys/socket.h>

#include?<arpa/inet.h>

#include?<string.h>

#include?<linux/netlink.h>

#define?NETLINK_TEST???????????20

??

struct?netlink_data{?

????????struct?nlmsghdr?msg;?

????????char?data[1024];?

};?

??

int?main()?

{?

????????struct?netlink_data?nldata;?

????????struct?nlmsghdr?*msg?=?&nldata.msg;?

????????int?retval;?

????????struct?sockaddr_nl?addr;?

????????char?*data?=?"hello?world!\0";?

????????int?size?=?strlen(data);?

????????//创建socket

????????int?fd?=?socket(PF_NETLINK,SOCK_RAW,NETLINK_TEST);?

????????if(fd<0)

????????{

????????????printf("socket?error");

????????????return?0;

????????}

????????//设置netlink消息头部信息

????????memset(&nldata,?'\0',?sizeof(nldata));?

????????msg->nlmsg_len?=?NLMSG_LENGTH(size);?//表示数据长度size+消息头部长度

????????msg->nlmsg_type?=?0;?

????????msg->nlmsg_flags?=?0;?

????????msg->nlmsg_seq?=?0;?

????????//设置接收信息的地址

????????addr.nl_family?=?AF_NETLINK;?

????????addr.nl_pid?=?0;?

????????addr.nl_groups?=?0;?

????????//拷贝信息到消息头后面

????????memcpy(NLMSG_DATA(msg),?data,?size);?

????????//发送消息

????????retval?=?sendto(fd,?&nldata,?msg->nlmsg_len,?0,?

????????????????????????(struct?sockaddr*)&addr,?sizeof(addr));?

??

????????close(fd);?

????????return?0;?

}?

(3)内核层代码

#include?<linux/module.h>

#include?<linux/init.h>

#include?<net/sock.h>

#include?<linux/netlink.h>

#include?<linux/inet.h>

#include?<linux/skbuff.h>

#define?NETLINK_TEST?20

struct?sock?*nl_sk?=?NULL;

void?test(struct?sk_buff?*__skb)

{

??????struct?sk_buff?*skb;

??????struct?nlmsghdr?*nlh;

??????//获取对skb的引用指针

??????skb=skb_get(__skb);

??????if(skb->len<NLMSG_SPACE(0))

??????{

???????????goto?free;

??????}

??????nlh=(struct?nlmsghdr?*)skb->data;

??????printk("msg:%s\n",(char?*)NLMSG_DATA(nlh));

free:

??????kfree_skb(skb);

}

static?int?__init?netlink_init(void)

{

?????//创建内核sock

?????nl_sk=netlink_kernel_create(&init_net,NETLINK_TEST,0,test,NULL,THIS_MODULE);

?????if(!nl_sk)

?????{

?????????printk("netlink:can?not?create");

?????????return?0;

?????}

?????else

?????{

????? printk("netlink:create?success!");

????????return?1;

?????}

}

static?void?__exit?netlink_exit(void)

{

?????if(nl_sk)

?????{

???????????//回收内核sock

???????????netlink_kernel_release(nl_sk);

?????}

}

MODULE_LICENSE("GPL");

module_init(netlink_init);

module_exit(netlink_exit);

(4)常用结构

struct?sockaddr_nl

{

????????sa_family_t?????nl_family;??????/*?AF_NETLINK???*/

????????unsigned?short??nl_pad;?????????/*?zero?????????*/

????????__u32???????????nl_pid;?????????/*?port?ID??????*/

????????__u32???????????nl_groups;??????/*?multicast?groups?mask?*/

};

struct?nlmsghdr

{

????????__u32???????????nlmsg_len;??????/*?Length?of?message?including?header?*/

????????__u16???????????nlmsg_type;?????/*?Message?content?*/

????????__u16???????????nlmsg_flags;????/*?Additional?flags?*/

????????__u32???????????nlmsg_seq;??????/*?Sequence?number?*/

????????__u32???????????nlmsg_pid;??????/*?Sending?process?port?ID?*/

};

(5)nlmsghdr常用宏

#define?NLMSG_HDRLEN??((int)?NLMSG_ALIGN(sizeof(struct?nlmsghdr)))//获取头部大小

#define?NLMSG_LENGTH(len)?((len)+NLMSG_ALIGN(NLMSG_HDRLEN))//获取头部+信息大小

#define?NLMSG_SPACE(len)?NLMSG_ALIGN(NLMSG_LENGTH(len))?//获取分配空间大小

#define?NLMSG_DATA(nlh)??((void*)(((char*)nlh)?+?NLMSG_LENGTH(0)))?//获取数据开始位置

<!--EndFragment-->

热点排行