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 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;
}
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;
}
相关文章推荐
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 《Linux 系统内核空间与用户空间通信的实现与分析》 Netlink 机制实现
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 用户空间与内核空间数据交换的方式(9)------netlink
- 用户与内核空间数据交换的方式(9)-netlink
- Linux Netlink 内核与用户间进行双向数据传输
- 用户空间与内核空间数据交换的方式(9)------netlink
- linux驱动开发--copy_to_user 、copy_from_user函数实现内核空间数据与用户空间数据的相互访问
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 用户空间与内核空间数据交换的方式(9)------netlink
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 基于NETLINK的内核与用户空间共享内存的实现
- 使用netlink机制实现内核空间和用户空间的双向消息通讯
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 用户空间与内核的交互---NETLINK
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 基于NETLINK的内核与用户空间共享内存的实现
- 用户与内核空间数据交换的方式(9)-netlink
- Netlink 套接字(内核与用户应用间进行双向数据传输的非常好的方式)
- Linux 系统内核空间与用户空间通信的实现与分析-NETLINK (转载)