您的位置:首页 > 其它

netlink实现用户态和内核态数据交互

2017-09-20 15:27 423 查看
本文代码实现:用户进程发送“nihao”给内核,内核回复“niyehao”给用户态。

1:netlink.h添加自己的宏。
2:编写用户态程序。
3:编写内核态程序。

内核态,需要全局变量进行数据的交互。

在模块init的时候,可以:
netlinkfd = netlink_kernel_create(&init_vrf, NL_MY, 0, kernel_receive, NULL, THIS_MODULE);
NL_MY 是加在 netlink.h 头文件中的宏。
kernel_recv 是自定义的函数的地址,用以接收处理用户态的数据
int process_message_thread(void *arg)
{
struct sk_buff *skb = (struct sk_buff *)(arg);
struct sk_buff *newskb;
int opp_id;
struct struReq_s *msg = (struct struReq_s *) skb->data;
opp_id = msg->pid;

struct struReq_s *needtosend = kmalloc(sizeof(struct struReq_s) + strlen("niyehao"),GFP_KERNEL);
needtosend->data_len = strlen("niyehao");
memcpy(needtosend->data,"niyehao", needtosend->data_len);
newskb = alloc_skb(sizeof(struct struReq_s) + strlen("niyehao"), GFP_ATOMIC);
skb_put(newskb,sizeof(struct struReq_s) + strlen("niyehao"));
memcpy(newskb->data,needtosend,sizeof(struct struReq_s) + strlen("niyehao"));
netlink_unicast(netlinkfd, newskb, opp_id, MSG_DONTWAIT);
kfree(needtosend);
return 0;
}
u32 nt = 0;
void kernel_receive(struct sk_buff *skb)
{
printk("#########recv###########\n");
process_message_thread(skb);
printk("#########leave###########\n");
}


用户态程序:
int netlink_socket = -1;

int main()
{

struct sockaddr_nl src_addr;
s32 ret;

struct struReq_s
{
int pid;
int data_len;
char data[0];
};
u8 buf[1024] = {0};
struct struReq_s *struReq = NULL;
netlink_socket = socket(AF_NETLINK, SOCK_RAW, NL_MY);
if(netlink_socket < 0)
{
return -1;
}
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid();
src_addr.nl_groups = 1;

ret = bind(netlink_socket, (struct sockaddr *)&src_addr, sizeof(src_addr));
if(ret < 0)
{
return -1;
}
struReq = malloc(sizeof( struct struReq_s) + 10);
if(struReq == NULL)
{
printf("malloc fail\n");
return 0;
}
memset(struReq, 0, sizeof(struct struReq_s) + 10);

struReq->pid = getpid();
struReq->data_len = 10;
memcpy(struReq->data,"nihao",strlen("nihao"));

memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = 0;
src_addr.nl_groups = 0;
if(sendto(netlink_socket, struReq, struReq->data_len + sizeof(struct struReq_s), 0,
(struct sockaddr *)&src_addr, sizeof(src_addr)) < 0)
{
return -1;
}

printf("user recv\n");
/*阻塞的读*/
memset(buf,0,1024);
recv(netlink_socket,buf,1024,0);
printf("recv from kernel len : %d\n",((struct struReq_s *)buf)->data_len);
printf("recv from kernel data: %s\n",((struct struReq_s *)buf)->data);

free(struReq);
close(netlink_socket);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐