linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据
来源:互联网 发布:网络和信息安全责任书 编辑:程序博客网 时间:2024/05/22 02:18
Linux 内核提供 copy_from_user()/copy_to_user() 函数来实现内核态与用户态数据的拷贝,但这两个函数会引发阻塞,所以不能用在硬、软中断中。一般将这两个特殊拷贝函数用在类似于系统调用一类的函数中
在下面的代码中,内核模块注册了一组设置套接字选项的函数使得用户空间进程可以调用此组函数对内核态数据进行读写。
下面是有关操作步骤及源代码:
头文件:imp1.h
/*imp1.h*/
#ifndef __IMP1_H__
#define __IMP1_H__
#define IMP1_OPS_BASIC 128
#define IMP1_SET IMP1_OPS_BASIC
#define IMP1_GET IMP1_OPS_BASIC
#define IMP1_MAX IMP1_OPS_BASIC+1
#endif
module:
编译:gcc -c -D__KERNEL__ -DMODULE imp1_k.c
查看module输出:方法一:dmesg
方法二:tail -f /var/log/messages
/*imp1_k.c*/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include "imp1.h"
#define KMSG "a message from kernel/n"
#define KMSG_LEN sizeof("a message from kernel/n")
static int data_to_kernel(struct sock *sk, int cmd, void *user,
unsigned int len)
{
switch(cmd)
{
case IMP1_SET:
{
char umsg[64];
memset(umsg, 0, sizeof(char)*64);
copy_from_user(umsg, user, sizeof(char)*64);
printk("umsg: %s", umsg);
}
break;
}
return 0;
}
static int data_from_kernel(struct sock *sk, int cmd, void *user, int *len)
{
switch(cmd)
{
case IMP1_GET:
{
copy_to_user(user, KMSG, KMSG_LEN);
}
break;
}
return 0;
}
static struct nf_sockopt_ops imp1_sockops =
{
.pf = PF_INET,
.set_optmin = IMP1_SET,
.set_optmax = IMP1_MAX,
.set = data_to_kernel,
.get_optmin = IMP1_GET,
.get_optmax = IMP1_MAX,
.get = data_from_kernel,
};
static int __init init(void)
{
return nf_register_sockopt(&imp1_sockops);
}
static void __exit fini(void)
{
nf_unregister_sockopt(&imp1_sockops);
}
module_init(init);
module_exit(fini);
用户测试程序:
编译:gcc -o user imp1_u.c
/*imp1_u.c*/
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <linux/in.h>
#include "imp1.h"
#define UMSG "a message from userspace/n"
#define UMSG_LEN sizeof("a message from userspace/n")
char kmsg[64];
int main(void)
{
int sockfd;
int len;
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if(sockfd < 0)
{
printf("can not create a socket/n");
return -1;
}
/*call function data_to_kernel()*/
setsockopt(sockfd, IPPROTO_IP, IMP1_SET, UMSG, UMSG_LEN);
len = sizeof(char)*64;
/*call function data_from_kernel()*/
getsockopt(sockfd, IPPROTO_IP, IMP1_GET, kmsg, &len);
printf("kmsg: %s", kmsg);
close(sockfd);
return 0;
}
用insmod加载module
用rmmod删除module
用lsmod查看有没有加载成功
dmesg:
umsg: a message from userspace
umsg: a message from userspace
[root@localhost ipc_sockopt]# ./user
kmsg: a message from kernel
[root@localhost ipc_sockopt]# ./user
kmsg: a message from kernel
- linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据
- linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据
- linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据
- 使用sockopt与内核交换数据
- 使用sockopt实现内核与用户之间通信
- Linux内核工程导论——进程:内核与用户空间的进程通信
- netfilter内核态与用户态 通信 之 sockopt
- netfilter内核态与用户态 通信 之 sockopt
- netfilter内核态与用户态 通信 之 sockopt
- Linux内核态与用户态进程通信方法-用户上下文
- Linux Kernel 学习笔记17:内核与用户层通信之sockopt
- 用户进程与内核IO通信的数据结构说明
- 用户进程与内核进程通信netlink实例
- (11)《基于Linux的C编程与内核导读》--进程间管道通信(一)
- linux系统的内核进程/用户进程和轻量级进程区别与联系
- Linux内核态与用户态通信的常用方法
- Linux内核态与用户态通信的常用方法
- Linux内核态与用户态通信的常用方法
- 日期格式转换
- 涙そうそう
- TStringList的一些高级用法
- 多项删除
- Web服务器中文URL研究心得(学习所得,跟大家分享)
- linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据
- 用代码修改Web.Config里的键值
- 软件项目管理之四:高效的管理优先权
- osworkflow配置说明
- 在Asp.net中利用OWC11画统计图(柱状图,饼状图及线状图等)及补充
- webservice 提示远程连接已经关闭的解决方法
- 一封来自大学老师的信——给所有还在大学中徘徊的人
- 创造很快乐
- dojo学习笔记(二) dojo.lang.array & dojo.lang.func & dojo.string.extras