国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站開(kāi)發(fā)目錄結(jié)構(gòu)百度首頁(yè)排名怎么做到

網(wǎng)站開(kāi)發(fā)目錄結(jié)構(gòu),百度首頁(yè)排名怎么做到,常州網(wǎng)站建設(shè)公司市場(chǎng),wordpress減少數(shù)據(jù)庫(kù)連接linux用戶(hù)態(tài)與內(nèi)核態(tài)通過(guò)字符設(shè)備交互 簡(jiǎn)述 Linux設(shè)備分為三類(lèi),字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)接口設(shè)備。字符設(shè)備只能一個(gè)字節(jié)一個(gè)字節(jié)讀取,常見(jiàn)外設(shè)基本都是字符設(shè)備。塊設(shè)備一般用于存儲(chǔ)設(shè)備,一塊一塊的讀取。網(wǎng)絡(luò)設(shè)備,Linux將對(duì)網(wǎng)絡(luò)…

linux用戶(hù)態(tài)與內(nèi)核態(tài)通過(guò)字符設(shè)備交互

簡(jiǎn)述

Linux設(shè)備分為三類(lèi),字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)接口設(shè)備。字符設(shè)備只能一個(gè)字節(jié)一個(gè)字節(jié)讀取,常見(jiàn)外設(shè)基本都是字符設(shè)備。塊設(shè)備一般用于存儲(chǔ)設(shè)備,一塊一塊的讀取。網(wǎng)絡(luò)設(shè)備,Linux將對(duì)網(wǎng)絡(luò)通信抽象成一個(gè)設(shè)備,通過(guò)套接字對(duì)其進(jìn)行操作。

在這里插入圖片描述

對(duì)于字符設(shè)備的用戶(hù)態(tài)與內(nèi)核態(tài)交互,主要涉及到打開(kāi)、讀取、寫(xiě)入、關(guān)閉等操作。通過(guò)字符設(shè)備實(shí)現(xiàn)內(nèi)核與用戶(hù)程序的交互,設(shè)計(jì)實(shí)現(xiàn)一個(gè)內(nèi)核態(tài)監(jiān)控文件目錄及文件復(fù)制拷貝的內(nèi)核模塊程序,其中字符設(shè)備交互時(shí)序圖如下:

user_space kernel_space 發(fā)送監(jiān)控目錄信息(list) 回復(fù)監(jiān)控目錄信息已設(shè)置 user_space kernel_space

通信協(xié)議格式

[2bytes數(shù)據(jù)長(zhǎng)度] + |2bytes目錄路徑數(shù)量| + |2bytes 長(zhǎng)度| + |目錄數(shù)據(jù)| + ... + |2bytes 長(zhǎng)度| + |目錄數(shù)據(jù)|

控制命令定義

#include <linux/ioctl.h>#define BASEMINOR 0
#define COUNT 5
#define NAME "ioctl_test"#define IOCTL_TYPE 'k'//定義無(wú)參的命令
#define IOCTL_NO_ARG _IO(IOCTL_TYPE, 1)//用戶(hù)空間向內(nèi)核空間寫(xiě)
#define IOCTL_WRITE_INT _IOW(IOCTL_TYPE, 2,int)//用戶(hù)空間從內(nèi)核空間讀
#define IOCTL_READ_INT _IOR(IOCTL_TYPE, 3, int)//用戶(hù)空間向內(nèi)核空間寫(xiě)
#define IOCTL_WRITE_STRING _IOW(IOCTL_TYPE, 4,char*)//用戶(hù)空間從內(nèi)核空間讀
#define IOCTL_READ_STRING _IOR(IOCTL_TYPE, 5, char*)#define IOCTL_MAXNR 5

上述命令實(shí)現(xiàn)了用戶(hù)態(tài)向內(nèi)核態(tài)寫(xiě)入、讀取int型或string類(lèi)型的數(shù)據(jù),定義控制命令個(gè)數(shù)為5

用戶(hù)態(tài)程序

#include <stdio.h>
#include <string.h>
#include <linux/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include "cmd.h"
enum arg_type{ARG_INT,ARG_STRING
};
union data{int integer;char string[255];};struct arg_node{int type; //字符串類(lèi)型union data arg_data;struct arg_node*next;
};
void insert_node(struct arg_node**head, struct arg_node * item ){if(item==NULL){printf("待插入節(jié)點(diǎn)指針為空\(chéng)n");return ;}if(*head == NULL){*head = item;printf("節(jié)點(diǎn)指針賦值,%p\n",*head);}else{struct arg_node *current = *head;while(current->next != NULL){current = current->next;}current->next = item;}}//參數(shù)格式:user_ipc -int 200 -string "12324154"
int main(int argc, char *argv[])
{if(argc<2 || argc%2==0){printf("參數(shù)個(gè)數(shù)不匹配\n");return -1;}int fd = 0;int arg = 0;fd = open("/dev/ioctl_test", O_RDWR);if(fd < 0){printf("open memdev0 failed!\n");return -1;}if(ioctl(fd, IOCTL_NO_ARG, &arg) < 0){printf("----打印命令傳輸失敗----\n");return -1;}unsigned char *protocol_body = NULL;int init_length = 5;int realloc_length = 10;int len_tag_bytes = 2;protocol_body = calloc(init_length, sizeof(unsigned char )*init_length);int index = 4;int num_of_dirs = 0;struct arg_node *p_head = NULL;int i=0;for(i=1; i<argc; i=i+2){if(strcmp(argv[i],"-int") == 0){struct arg_node*p_item = malloc(sizeof(struct arg_node));p_item->next = NULL;p_item->type = ARG_INT;p_item->arg_data.integer = atoi(argv[i+1]);insert_node(&p_head, p_item);printf("插入int類(lèi)型,值: %d \n",p_item->arg_data.integer);if(p_head==NULL)printf("鏈表頭指針為空\(chéng)n");}else if(strcmp(argv[i], "-string") == 0){struct arg_node *p_item = malloc(sizeof(struct arg_node));p_item->next = NULL;		p_item->type = ARG_STRING;memcpy(p_item->arg_data.string, argv[i+1],strlen(argv[i+1]));insert_node(&p_head, p_item);printf("插入string類(lèi)型,值: %s \n",p_item->arg_data.string);//插入值組裝協(xié)議數(shù)據(jù)包[2bytes數(shù)據(jù)長(zhǎng)度] + [2bytes 字符串?dāng)?shù)量] +[2bytes長(zhǎng)度] + [目錄絕對(duì)路徑] ... + [2bytes長(zhǎng)度] + [目錄絕對(duì)路徑]int length = strlen(argv[i+1]);if((index+len_tag_bytes+length) > init_length) //空間不夠,再分配{realloc_length = length + len_tag_bytes + 1; //計(jì)算再分配字節(jié),多分配1個(gè)字節(jié),作為結(jié)束nullprotocol_body = realloc(protocol_body, sizeof(unsigned char)*(init_length + realloc_length));if(!protocol_body){printf("再分配空間失敗\n");exit(-1);}memset(protocol_body+index, 0, sizeof(unsigned char)*(init_length + realloc_length)); //初始化再分配空間為零init_length += realloc_length;printf("新分配空間成功,新分配空間字節(jié)大小 %d,總空間大小 %d\n",realloc_length, init_length);}protocol_body[index] = length / 256 ;protocol_body[index + 1] = length % 256;index = index + 2;memcpy(protocol_body + index, argv[i+1],length);index = index + length;num_of_dirs++;}}index = index -2;protocol_body[0] = index / 256;protocol_body[1] = index % 256;protocol_body[2] = num_of_dirs /256;protocol_body[3] = num_of_dirs %256;printf("組包數(shù)據(jù):%d\n",index);for(i=0; i<index+2; i++){printf("%02x ",protocol_body[i]);}printf("\n");//內(nèi)核交互 -- 字符設(shè)備if(ioctl(fd, IOCTL_WRITE_STRING, protocol_body)<0){printf("----用戶(hù)態(tài)向內(nèi)核寫(xiě)入字符串?dāng)?shù)據(jù)失敗----\n");return -1;}char recv[256]={0};if(ioctl(fd,IOCTL_READ_STRING,recv)<0){printf("----用戶(hù)態(tài)從內(nèi)核態(tài)讀取字符串?dāng)?shù)據(jù)失敗----\n");return -1;}printf("從內(nèi)核態(tài)讀取數(shù)據(jù):%s\n",recv);//釋放申請(qǐng)內(nèi)存free(protocol_body);protocol_body = NULL;close(fd);return 0;
}

上述代碼實(shí)現(xiàn)把多個(gè)int或者char*類(lèi)型的數(shù)據(jù)插入鏈表中,但是實(shí)際使用中,這個(gè)鏈表比沒(méi)有用,和用戶(hù)態(tài)交互,我只使用了string類(lèi)型的數(shù)據(jù),再把數(shù)據(jù)存入到protocol_body中,通過(guò)控制命令I(lǐng)OCTL_WRITE_STRING,實(shí)現(xiàn)把protocol_body寫(xiě)入到字符設(shè)備,供內(nèi)核模塊讀取,同時(shí)內(nèi)核模塊返回一個(gè)隨機(jī)數(shù)。

編譯命令

gcc -o user_ipc user_ipc.c

內(nèi)核模塊

//msg_recv_send.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/ioctl.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
#include <linux/random.h>
#include "cmd.h"
#include "ctl_data.h"dev_t dev_num;
struct cdev *cdevp = NULL;/*
struct dir_node{int length; //長(zhǎng)度char *dir_s; //目錄字符串struct list_head list; //鏈表
};
*/
LIST_HEAD(msg_list_head);//處理
int handle_recv_msg(char *msg, int len){int ret = 0;int dir_index=0;//清空鏈表struct dir_node *entry, *tmp;list_for_each_entry_safe(entry, tmp, &msg_list_head,list){list_del(&entry->list);kfree(entry->dir_s);kfree(entry);}//解析數(shù)據(jù)int dir_length = 0;int num_of_dirs = 0;int char_index = 2;num_of_dirs = msg[0]<<8 | msg[1];for(dir_index=0; dir_index<num_of_dirs; dir_index++){dir_length = msg[char_index]<<8 | msg[char_index+1];char_index = char_index + 2;struct dir_node * new_node = kmalloc(sizeof(struct dir_node),GFP_KERNEL);new_node->dir_s = kmalloc(sizeof(char)*(dir_length+1),GFP_KERNEL);memset(new_node->dir_s, 0, dir_length+1);new_node->length = dir_length;INIT_LIST_HEAD(&new_node->list);memcpy(new_node->dir_s, msg+char_index, dir_length);char_index = char_index + dir_length;list_add_tail(&new_node->list, &msg_list_head);}//遍歷列表list_for_each_entry(entry, &msg_list_head, list){printk(KERN_INFO "接收數(shù)據(jù):%s\n",entry->dir_s);}	return ret;
}
static long my_ioctl(struct file * filp, unsigned int cmd, unsigned long arg){long ret = 0;int err = 0;int ioarg = 0;char kernel_buffer[256];unsigned int random_value = 0;		if(_IOC_TYPE(cmd) != IOCTL_TYPE){return -EINVAL;}if(_IOC_NR(cmd) > IOCTL_MAXNR){return -EINVAL;}if(_IOC_DIR(cmd) & _IOC_READ){err = !access_ok((void*)arg, _IOC_SIZE(cmd));}else if(_IOC_DIR(cmd) & _IOC_WRITE){err = !access_ok((void*)arg, _IOC_SIZE(cmd));}if(err){return -EFAULT;}switch(cmd){case IOCTL_NO_ARG:printk(KERN_INFO "print not arg cmd\n");break;case IOCTL_WRITE_INT:ret = __get_user(ioarg, (int*)arg);printk(KERN_INFO "get data from user space is :%d\n", ioarg);break;case IOCTL_READ_INT:ioarg = 1101;ret = __put_user(ioarg, (int *)arg);break;case IOCTL_WRITE_STRING:memset(kernel_buffer, 0, sizeof(kernel_buffer));unsigned char len[3]={0};ret = copy_from_user(len, (char*)arg, 2);int recv_len = 0;recv_len = len[0]*256 + len[1];printk(KERN_INFO "用戶(hù)態(tài)寫(xiě)入的數(shù)據(jù)長(zhǎng)度 %d",len[0]*256+len[1]);char *recv_buffer = kmalloc(sizeof(char)*recv_len,GFP_KERNEL);ret = copy_from_user(recv_buffer, (unsigned char*)(arg+2), recv_len);if(ret!=0){printk(KERN_INFO "從用戶(hù)態(tài)拷貝數(shù)據(jù)失敗,失敗字節(jié)數(shù) %d\n",ret);}printk(KERN_INFO "get data from user space is :%*ph\n",recv_len, recv_buffer);//處理接收到的字符串handle_recv_msg(recv_buffer, recv_len);kfree(recv_buffer);break;case IOCTL_READ_STRING://memset(random_value, 0, sizeof(random_value));memset(kernel_buffer, 0, sizeof(kernel_buffer));random_value = get_random_int();snprintf(kernel_buffer, sizeof(kernel_buffer),"返回隨機(jī)字符串?dāng)?shù)值:%u",random_value);printk(KERN_INFO "kern_buffer : %s\n",kernel_buffer);ret = copy_to_user((char *)arg,kernel_buffer,sizeof(kernel_buffer));if(ret == 0){printk(KERN_INFO "寫(xiě)文本字符到用戶(hù)態(tài)成功,[%s]。\n",(char*)arg);}else{printk(KERN_INFO "寫(xiě)文本字符到用戶(hù)態(tài)失敗,未寫(xiě)入字節(jié)數(shù) %d。\n",ret);}break;default:return -EINVAL;}return ret;
}static const struct file_operations fops = {.owner = THIS_MODULE,.unlocked_ioctl = my_ioctl
};int __init ioctl_init(void ){int ret ;ret = alloc_chrdev_region(&dev_num, BASEMINOR, COUNT, NAME);if(ret < 0){printk(KERN_ERR "alloc_chrdev_region failed...\n");goto err1;}printk(KERN_INFO, "major = %d\n",MAJOR(dev_num));cdevp = cdev_alloc();if(NULL == cdevp){printk(KERN_ERR "cdev_alloc failed...\n");ret = -ENOMEM;goto err2;}cdev_init(cdevp, &fops);ret = cdev_add(cdevp, dev_num, COUNT);if(ret < 0){printk(KERN_INFO "cdev_add failed...\n");goto err2;}printk(KERN_INFO "------init completely\n");return 0;
err2:unregister_chrdev_region(dev_num, COUNT);
err1:return ret;
}void __exit ioctl_exit(void){cdev_del(cdevp);unregister_chrdev_region(dev_num, COUNT);printk(KERN_INFO "exit success.");
}

上述代碼中alloc_chrdev_region分配一個(gè)名為NAME的字符設(shè)備,

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
//dev 字符設(shè)備存儲(chǔ)的指針,高12位是主設(shè)備號(hào),低20位是從設(shè)備號(hào)
//baseminor是從設(shè)備號(hào)
//count 請(qǐng)求的設(shè)備號(hào)數(shù)量
//name  設(shè)備名

內(nèi)核模塊主文件

//file_shield.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/unistd.h>
#include <asm/ptrace.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/cred.h>
#include "hook_func.h"
#include "ctl_data.h"
#include "msg_recv_send.h"MODULE_LICENSE("GPL");//增加字符設(shè)備處理邏輯代碼static int __init file_shield_init(void){int ret = 0;printk(KERN_INFO "init completly");//創(chuàng)建字符設(shè)備ioctl_init();printk(KERN_INFO "模塊已加載\n");return ret;
}
static void __exit file_shield_exit(void){//卸載字符設(shè)備ioctl_exit();printk(KERN_INFO "模塊已卸載\n");
}
module_init(file_shield_init);
module_exit(file_shield_exit);

內(nèi)核模塊Makefile

KERNELDIR:=/lib/modules/$(shell uname -r)/build
EXTRA_CFLAGS +=-O1PWD = $(shell pwd)obj-m +=file_hook.o
file_hook-objs:=file_shield.o msg_recv_send.o all:make -C $(KERNELDIR) M=$(PWD) modules
clean:make -C $(KERNELDIR) M=$(PWD) clean

編譯

sudo make

輸出

 LD [M]  /home/admin01/file-shield/file_hook.oBuilding modules, stage 2.MODPOST 1 modulesCC [M]  /home/admin01/file-shield/file_hook.mod.oLD [M]  /home/admin01/file-shield/file_hook.ko
make[1]: 離開(kāi)目錄“/usr/src/linux-headers-5.4.18-53-generic”

設(shè)備節(jié)點(diǎn)文件

在Linux系統(tǒng)中,設(shè)備節(jié)點(diǎn)文件是一種用于與設(shè)備進(jìn)行交互的接口。這些設(shè)備節(jié)點(diǎn)文件通常位于/dev目錄下。在Linux系統(tǒng)中,設(shè)備節(jié)點(diǎn)文件是一種用于與設(shè)備進(jìn)行交互的接口。這些設(shè)備節(jié)點(diǎn)文件通常位于/dev目錄下。

設(shè)備節(jié)點(diǎn)文件是Linux中的一種特殊文件,用于與設(shè)備進(jìn)行通信。它們?cè)试S用戶(hù)空間程序通過(guò)標(biāo)準(zhǔn)的文件I/O操作(如打開(kāi)、讀取、寫(xiě)入、關(guān)閉)來(lái)與設(shè)備進(jìn)行交互。在/dev目錄下的每個(gè)設(shè)備節(jié)點(diǎn)文件都對(duì)應(yīng)一個(gè)特定的設(shè)備或設(shè)備類(lèi)。

在內(nèi)核模塊中注冊(cè)字符設(shè)備時(shí),通常使用cdev_add函數(shù),它會(huì)告訴內(nèi)核創(chuàng)建相應(yīng)的設(shè)備節(jié)點(diǎn)文件。這些設(shè)備節(jié)點(diǎn)文件將在/dev目錄下動(dòng)態(tài)創(chuàng)建,以便用戶(hù)空間程序能夠訪(fǎng)問(wèn)注冊(cè)的設(shè)備。

例如,如果你的設(shè)備被命名為my_device,在/dev目錄下將創(chuàng)建一個(gè)名為my_device的設(shè)備節(jié)點(diǎn)文件。用戶(hù)空間程序可以通過(guò)打開(kāi)/dev/my_device來(lái)訪(fǎng)問(wèn)你的設(shè)備。

需要手動(dòng)創(chuàng)建一個(gè)設(shè)備節(jié)點(diǎn)文件

sudo mknod /dev/ioctl_test c 240 0

加載內(nèi)核模塊

sudo insmod path/file_hook.ko

卸載內(nèi)核模塊

sudo rmmod file_hook

測(cè)試

用戶(hù)態(tài)程序發(fā)送接收
在這里插入圖片描述

內(nèi)核模塊發(fā)送與接收
在這里插入圖片描述

http://aloenet.com.cn/news/44344.html

相關(guān)文章:

  • 做ppt模板網(wǎng)站有哪些網(wǎng)站統(tǒng)計(jì)
  • 做自己網(wǎng)站彩票免費(fèi)站長(zhǎng)工具
  • 寶安有效的網(wǎng)站制作站長(zhǎng)域名查詢(xún)工具
  • python源碼分享網(wǎng)站百度客服24小時(shí)人工服務(wù)
  • wordpress消息系統(tǒng)滕州網(wǎng)站建設(shè)優(yōu)化
  • 淘寶開(kāi)店網(wǎng)站怎么做網(wǎng)絡(luò)稿件投稿平臺(tái)
  • 可以做照片書(shū)的網(wǎng)站百度推廣入口
  • next 主題wordpress谷歌seo招聘
  • 用內(nèi)網(wǎng)穿透做網(wǎng)站可以被收錄嗎淘寶關(guān)鍵詞搜索工具
  • 懷柔網(wǎng)站制作煙臺(tái)seo網(wǎng)絡(luò)推廣
  • 淄博 網(wǎng)站建設(shè)免費(fèi)網(wǎng)站在線(xiàn)客服系統(tǒng)源碼
  • 貴州住房和城鄉(xiāng)建設(shè)部網(wǎng)站官網(wǎng)阿里關(guān)鍵詞排名查詢(xún)
  • 德升武漢網(wǎng)站建設(shè)推廣哪個(gè)網(wǎng)站好
  • 談?wù)劸W(wǎng)站的開(kāi)發(fā)流程長(zhǎng)沙網(wǎng)站優(yōu)化seo
  • 網(wǎng)站建設(shè) 書(shū)籍下載廣告推廣方案怎么寫(xiě)
  • 做一個(gè)網(wǎng)站人員seo運(yùn)營(yíng)是什么
  • 深圳鹽田建設(shè)交易中心網(wǎng)站什么叫軟文
  • wwe中文官網(wǎng)站網(wǎng)站一級(jí)域名和二級(jí)域名區(qū)別
  • 廣州行業(yè)網(wǎng)站建設(shè)武漢seo公司出 名
  • 開(kāi)發(fā)一個(gè)企業(yè)網(wǎng)站需要多少錢(qián)百度認(rèn)證服務(wù)平臺(tái)
  • 車(chē)牌照損壞在網(wǎng)站做的能用嗎吉林seo外包
  • 網(wǎng)站建設(shè)成本價(jià)長(zhǎng)沙免費(fèi)建站網(wǎng)絡(luò)營(yíng)銷(xiāo)
  • 輿情監(jiān)測(cè)系統(tǒng)永久免費(fèi)seo整站優(yōu)化哪家專(zhuān)業(yè)
  • 河南網(wǎng)絡(luò)推廣那家好煙臺(tái)seo快速排名
  • 做企業(yè)網(wǎng)站開(kāi)發(fā)哪家好網(wǎng)絡(luò)推廣工作室
  • 怎么用vps搭建網(wǎng)站無(wú)錫百度信息流
  • 成都網(wǎng)站開(kāi)發(fā)價(jià)格沈陽(yáng)seo整站優(yōu)化
  • 連云港做網(wǎng)站公司哪家好推廣文案
  • 天津平臺(tái)網(wǎng)站建設(shè)制作班級(jí)優(yōu)化大師的利和弊
  • wordpress懸浮窗口seo推廣收費(fèi)標(biāo)準(zhǔn)