日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据

發(fā)布時間:2023/12/8 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
linux學(xué)習(xí)?內(nèi)核提供 copy_from_user()/copy_to_user() 函數(shù)來實現(xiàn)內(nèi)核態(tài)與用戶態(tài)數(shù)據(jù)的拷貝,但這兩個函數(shù)會引發(fā)阻塞,所以不能用在硬、軟中斷中。一般將這兩個特殊拷貝函數(shù)用在類似于系統(tǒng)調(diào)用一類的函數(shù)中

???? 在下面的代碼中,內(nèi)核模塊注冊了一組設(shè)置套接字選項的函數(shù)使得用戶空間進(jìn)程可以調(diào)用此組函數(shù)對內(nèi)核態(tài)數(shù)據(jù)進(jìn)行讀寫。

????下面是有關(guān)操作步驟及源代碼:

頭文件: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


轉(zhuǎn)于:http://blog.csdn.net/max415/article/details/2051330

總結(jié)

以上是生活随笔為你收集整理的linux 内核进程与用户进程的通信 方法一 使用sockopt与内核交换数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。