基于內核模塊的測試代碼編寫(3)

發表于:2014-08-03來源:uml.org.cn作者:fvceww點擊數: 標簽:測試代碼
向內核中注冊/proc下文件的調用是 create_proc_entry,創建中需要指定文件名,訪問權限和父節點名,返回為指向 proc_dir_entry結構的指針。通過該返回指針,可

  向內核中注冊/proc下文件的調用是 create_proc_entry,創建中需要指定文件名,訪問權限和父節點名,返回為指向 proc_dir_entry結構的指針。通過該返回指針,可以進一步修改文件的用戶id,組id,綁定的內核數據等;但最為關鍵的是可以指定用戶讀或寫該文件時,在內核中被執行的回調函數。下面是一個向proc文件系統中注冊新文件的示例:

static int __init proc_module_init(void){
entry = create_proc_entry("astring", 0644, myprocroot);
if (entry) {
entry->data = &string_var;
entry->read_proc = &string_read_proc;
entry->write_proc = &string_write_proc;
}
return 0
}
static void __exit procfs_exam_exit(void){
remove_proc_entry("astring", myprocroot);
remove_proc_entry("myproctest", NULL);
}
//read proc
int string_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data){
count = sprintf(page, "%s", (char *)data);
return count;
}
//write proc
int string_write_proc(struct file *file, const char __user *buffer,
unsigned long count, void *data){
if (count > STR_MAX_SIZE) {
count = 255;
}
copy_from_user(data, buffer, count);
return count;
} 

  4.5 af_netlink

  netlink是一種特殊的socket,用于用戶態與內核態的雙向通訊。在實現用戶和內核交互的各種方式中,netlink的主要特點得意于它繼承了 socket的一些基本特性,包括異步通訊,多播,雙向性,不需要額外的文件。在用戶態中,netlink的使用與標準的socket API相同,在內核態,則需要使用專門的API。下面介紹具體的使用方法:

  在用戶態中,首先通過要創建socket,其中指定domain必須為AF_NETLINK,協議為通常SOCK_RAW,協議類型為NETLINK_GENERIC或其它自定義類型

  sd = socket(AF_NETLINK, SOCK_RAW,NETLINK_GENERIC);

  然后通過bind綁定源端的地址,地址結構定義如下,其中nl_family為AF_NETLINK,nl_pad 目前無用填充0,nl_pid為進程id,若為0代表內核;nl_groups用于組播時的組號。

struct sockaddr_nl {    
sa_family_t    nl_family;    
unsigned short nl_pad;  
  __u32         nl_pid;    
__u32          nl_groups;    
} saddr;  

bind(sd, (struct sockaddr*)&saddr, sizeof(saddr));

  通過sendmsg可以發送消息msg到指定的地址。

  ret = sendmsg(sd, &msg, 0);

  在msg的所有元素中,msg_name需要指向一個 sockaddr_nl 結構的首地址,用來表示發送的目的端的地址,如果是發送到內核,其中的nl_pid字段置為0;msg_iov是要發送消息集合的向量,向量中的每一項代表一條消息。每一項指向數據的首部為一個nlmsghdr結構,其字段定義了該條消息長度,消息類型,序號,發送者進程id等;隨后跟隨的是消息的主體數據部分。 當要接收消息時,通過recvmsg可以獲得類似的消息向量,從而獲得數據及發送者等有關信息。

  在內核態,通過netlink_kernel_create可以在內核中新建socket結構并注冊接收到消息的回調函數input,其原型為:

  struct sock * netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len));

  當接收到消息時,回調函數input中的sk指針就指向了剛剛創建的socket在內核中的結構,通過對該結構的訪問,可以獲得要接收的數據。一種基本的input實現如下:

void input (struct sock *sk, int len) {
struct sk_buff *skb;    
struct nlmsghdr *nlh = NULL;    
u8 *data = NULL;    
while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {    
nlh = (struct nlmsghdr *)skb->data;    
data = NLMSG_DATA(nlh);    
}       
}

  此外,sock_release是在內核中釋放socket的方法;而通過netlink_unicast和netlink_broadcast可以在內核中令netlink socket發送數據,具體的方法可以參考 http://blog.chinaunix.net/u/19940/showart_144827.html

  4.6 其它方法

  以上所介紹的方法具有一個共同特點,它們不需要較高版本的內核支持,添加新的功能不需要重新編譯內核或替代內核中的原有功能。當然,還有一些其它方法,可能會需要內核版本或重新編譯內核等條件的支持,但同樣能達到用戶態和內核態交互這一目標,比如修改或添加新的系統調用,或利用sysfs,relayfs 等特殊的虛擬文件系統。這里不再一一介紹。

原文轉自:http://www.uml.org.cn/Test/201210242.asp

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97