亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Linux服務器 > 正文

linux下用戶程序同內核通信詳解(netlink機制)

2024-09-05 23:04:33
字體:
來源:轉載
供稿:網友

簡介

linux/197206.html">linux下用戶程序同內核通信的方式一般有ioctl, proc文件系統,剩下一個就是Netlink套接字了。 這里先介紹下netlink。

Netlink 是一種在內核與用戶應用間進行雙向數據傳輸的非常好的方式,用戶態應用使用標準的 socket API 就可以使用 netlink 提供的強大功能,內核態需要使用專門的內核 API 來使用 netlink。

Netlink 相對于系統調用,ioctl 以及 /proc 文件系統而言具有以下優點:

1,為了使用 netlink,用戶僅需要在 include/linux/netlink.h 中增加一個新類型的 netlink 協議定義即可, 如 #define NETLINK_MYTEST 17 然后,內核和用戶態應用就可以立即通過 socket API 使用該 netlink 協議類型進行數據交換。但系統調用需要增加新的系統調用,ioctl 則需要增加設備或文件, 那需要不少代碼,proc 文件系統則需要在 /proc 下添加新的文件或目錄,那將使本來就混亂的 /proc 更加混亂。

2. netlink是一種異步通信機制,在內核與用戶態應用之間傳遞的消息保存在socket緩存隊列中,發送消息只是把消息保存在接收者的socket的接 收隊列,而不需要等待接收者收到消息,但系統調用與 ioctl 則是同步通信機制,如果傳遞的數據太長,將影響調度粒度。

3.使用 netlink 的內核部分可以采用模塊的方式實現,使用 netlink 的應用部分和內核部分沒有編譯時依賴,但系統調用就有依賴,而且新的系統調用的實現必須靜態地連接到內核中,它無法在模塊中實現,使用新系統調用的應用在編譯時需要依賴內核。

4.netlink 支持多播,內核模塊或應用可以把消息多播給一個netlink組,屬于該neilink 組的任何內核模塊或應用都能接收到該消息,內核事件向用戶態的通知機制就使用了這一特性,任何對內核事件感興趣的應用都能收到該子系統發送的內核事件,在 后面的文章中將介紹這一機制的使用。

5.內核可以使用 netlink 首先發起會話,但系統調用和 ioctl 只能由用戶應用發起調用。

6.netlink 使用標準的 socket API,因此很容易使用,但系統調用和 ioctl則需要專門的培訓才能使用。

下面這兩部分代碼主要的目的是用netlink機制實現用戶程序和內核的通信。 具體就是用戶程序執行./netlink -S [我是參數] 或./netlink -G 時,內核會返回"S know you!" 和“I know you!” 這兩種字符串, 然后輸出。 內核和用戶程序均加有打印。

內核模塊

1. Makefile依賴的編譯規則 ruler.dir

PWD := $(shell pwd)  all: modules romfs  modules:  $(MAKE) -C $(KDIR) M=$(PWD) modules  @echo $(OBJ)  modules_install:  $(MAKE) -C $(KDIR) M=$(PWD) modules_install  romfs:  cp -rf *.ko $(MODULES_BUILD_DIR)  clean:  rm *.o *.ko *.mod.* Module.* modules.*  rm -rf $(MODULES_BUILD_DIR)  obj-m := $(MOD_NAME).o 

2.Makefile

KERNEL_MODULES := netlink  export MODULES_ROOT_DIR := $(shell pwd) export MODULES_BUILD_DIR := $(MODULES_ROOT_DIR)/build export KDIR := /lib/modules/$(shell uname -r)/build #這行是為了取出系統下內核的目錄(ubuntu)  all: init modules romfs  init:  mkdir -p $(MODULES_BUILD_DIR)  modules:$(patsubst %, _dir_%, $(KERNEL_MODULES))  $(patsubst %, _dir_%, $(KERNEL_MODULES)):  @echo  @echo Building $(patsubst _dir_%, %, $@)  $(MAKE) -C $(patsubst _dir_%, %, $@) all   romfs: $(patsubst %, _romfs_%, $(KERNEL_MODULES)) $(patsubst %, _romfs_%, $(KERNEL_MODULES)):  $(MAKE) -C $(patsubst _romfs_%, %, $@) romfs   clean: $(patsubst %, _clean_%, $(KERNEL_MODULES))  $(RM) $(BUILD_DIR) $(patsubst %, _clean_%, $(KERNEL_MODULES)):  @echo  @echo Cleaning $(patsubst _dir_%, %, $@)  $(MAKE) -C $(patsubst _clean_%, %, $@) clean  .PHONY: 

3. ./netlink/netlink.c

/*  * netlink.c  *  * Created on: 2014 *  Author: cr  */  #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/types.h> #include <linux/sched.h> #include <linux/netlink.h> #include <net/sock.h> #include "usrlink.h"  MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("MDAXIA");  struct sock *netlink_fd;   static void netlink_to_user(int dest, void *buf, int len) {  struct nlmsghdr *nl;  struct sk_buff *skb;  int size;   size = NLMSG_SPACE(len);  skb = alloc_skb(size, GFP_ATOMIC);  if(!skb || !buf)  {   printk(KERN_ALERT "netlink_to_user skb of buf null!/n");   return;  }  nl = nlmsg_put(skb, 0, 0, 0, NLMSG_SPACE(len) - sizeof(struct nlmsghdr), 0);  NETLINK_CB(skb).pid = 0;  NETLINK_CB(skb).dst_group = 0;   memcpy(NLMSG_DATA(nl), buf, len);  nl->nlmsg_len = (len > 2) ? (len - 2):len;   netlink_unicast(netlink_fd, skb, dest, MSG_DONTWAIT);  printk(KERN_ALERT "K send packet success/n"); }  static int process_hello_get(int dest, void *buf, int len) {  printk(KERN_ALERT "In process_hello get!/n");  memcpy(buf, "I known you !", 13);  netlink_to_user(dest, buf, 13);  return NET_OK; }  static int process_hello_set(int dest, void *buf, int len) {  printk(KERN_ALERT "In process_hello set! %s/n", (char *)buf);  memcpy(buf, "S known you !", 13);  netlink_to_user(dest, buf, 13);  return NET_OK; }   static void netlink_process_packet(struct nlmsghdr *nl) {  int ret;   switch(nl->nlmsg_type)  {  case HELLO_GET:   ret = process_hello_get(nl->nlmsg_pid, NLMSG_DATA(nl), nl->nlmsg_len);   break;  case HELLO_SET:   ret = process_hello_set(nl->nlmsg_pid, NLMSG_DATA(nl), nl->nlmsg_len);   break;  default:break;  } }  static void netlink_recv_packet(struct sk_buff *__skb) {  struct sk_buff *skb;  struct nlmsghdr *nlhdr;   skb = skb_get(__skb);  if(skb->len >= sizeof(struct nlmsghdr))  {   nlhdr = (struct nlmsghdr *)skb->data;   if(nlhdr->nlmsg_len >= sizeof(struct nlmsghdr) &&     __skb->len >= nlhdr->nlmsg_len)   {    netlink_process_packet(nlhdr);   }  }  else   printk(KERN_ALERT "Kernel receive msg length error!/n"); }  static int __init netlink_init(void) {  netlink_fd = netlink_kernel_create(&init_net, USER_NETLINK_CMD, 0, netlink_recv_packet, NULL, THIS_MODULE);  if(NULL == netlink_fd)  {   printk(KERN_ALERT "Init netlink!/n");   return -1;  }  printk(KERN_ALERT "Init netlink success!/n");  return 0; }  static void __exit netlink_exit(void) {  netlink_kernel_release(netlink_fd);  printk(KERN_ALERT "Exit netlink!/n"); }  module_init(netlink_init); module_exit(netlink_exit); 

4. ./netlink/usrlink.h

/*  * usrlink.h  *  * Created on: 2014騫?鏈?7鏃? *  Author: cr  */ #ifndef USRLINK_H_ #define USRLINK_H_  #define USER_NETLINK_CMD 25 #define MAXMSGLEN   1024  typedef enum error_e {  NET_ERROR,  NET_OK,  NET_PARAM,  NET_MEM,  NET_SOCK, } netlink_err;  typedef enum module_e {  HELLO_CMD = 1, } netlink_module;  typedef enum type_e {  HELLO_SET,  HELLO_GET, } netlink_type;  #endif /* USRLINK_H_ */ 

5. ./netlink/Makefile

MOD_NAME := netlink  $(MOD_NAME)-objs : netlink.o  -include $(MODULES_ROOT_DIR)/rules.dir  .PHONY: 

6. 編譯方式。

其中Makefile、rulers.dir 在Knetlink/下, netlink.c 、netlink.h 、Makefile在Knetlink/netlink/目錄下。 編譯時在Knetlink目錄下執行Make即可

用戶程序

用戶程序的Makefile 這里就不放出了。 我是直接在eclipse下建的工程 自動編譯的、...

1. netlink.c

/*  * usrlink.c  *  * Created on: 2014騫?鏈?7鏃? *  Author: cr  */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "usrlink.h"  int netlink_sock_init(netlink_sock *netlink_s, int module, int protocol) {  netlink_s->sock = socket(PF_NETLINK, SOCK_RAW, protocol);  if(netlink_s->sock < 0)   return NET_SOCK;  memset(&netlink_s->src, 0 ,sizeof(netlink_s->src));  netlink_s->src.nl_family = AF_NETLINK;  netlink_s->src.nl_pid = module;  netlink_s->src.nl_groups = 0;   if(bind(netlink_s->sock, (struct sockaddr *)&netlink_s->src, sizeof(netlink_s->src)) < 0)   return NET_SOCK;   netlink_s->dest.nl_family = AF_NETLINK;  netlink_s->dest.nl_pid = 0;  netlink_s->dest.nl_groups = 0;   return NET_OK; }  int netlink_send(netlink_sock *netlink_s, int type, char *sbuf, int slen, char *rbuf, int *rlen) {  struct msghdr msg;  struct nlmsghdr *nlhdr = NULL;  struct iovec iov;  int ret;   nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAXMSGLEN));  if(NULL == nlhdr)   return NET_MEM;   memcpy(NLMSG_DATA(nlhdr), sbuf, slen);  nlhdr->nlmsg_len = NLMSG_SPACE(slen);  nlhdr->nlmsg_pid = netlink_s->src.nl_pid;  nlhdr->nlmsg_type = type;  nlhdr->nlmsg_flags = 0;   iov.iov_base = (void *)nlhdr;  iov.iov_len = nlhdr->nlmsg_len;   msg.msg_name = (void *)&(netlink_s->dest);  msg.msg_namelen = sizeof(netlink_s->dest);  msg.msg_iov = &iov;  msg.msg_iovlen = 1;   ret = sendmsg(netlink_s->sock, &msg, 0);  if(ret < 0)  {   printf("Send fail/n");   goto error;  }  ret = recvmsg(netlink_s->sock, &msg, 0);  if(ret < 0)  {   printf("Read fail/n");   goto error;  }  memcpy(rbuf, NLMSG_DATA(nlhdr), nlhdr->nlmsg_len);  *rlen = nlhdr->nlmsg_len;  return NET_OK;  error:  free(nlhdr);  return NET_SOCK; }  int netlink_sock_deinit(netlink_sock *netlink_s) {  close(netlink_s->sock);  memset(netlink_s, 0, sizeof(netlink_sock));  return NET_OK; } 

2. netlink.h

/*  * usrlink.h  *  * Created on: 2014 *  Author: cr  */ #include <sys/types.h> #include <sys/socket.h> #include <asm/types.h> #include <linux/socket.h> #include <linux/netlink.h> #ifndef USRLINK_H_ #define USRLINK_H_  #define USER_NETLINK_CMD 25 #define MAXMSGLEN   1024  typedef enum error_e {  NET_ERROR,  NET_OK,  NET_PARAM,  NET_MEM,  NET_SOCK, } netlink_err;  typedef enum module_e {  HELLO_CMD = 1, } netlink_module;  typedef enum type_e {  HELLO_SET,  HELLO_GET, } netlink_type;  typedef struct usr_sock_h {  int sock;  struct sockaddr_nl dest;  struct sockaddr_nl src; } netlink_sock;  int netlink_sock_init(netlink_sock *netlink_s, int module, int protocol); int netlink_sock_deinit(netlink_sock *netlink_s); int netlink_send(netlink_sock *netlink_s, int type, char *sbuf, int slen, char *rbuf, int *rlen);  #endif /* USRLINK_H_ */ 

3. main.c

/*  * main.c  *  * Created on: 2014騫?鏈?7鏃? *  Author: cr  */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "usrlink.h"  int parse_ret(int ret) {  switch(ret)  {  case NET_OK:   return ret;  case NET_ERROR:   printf("error/n");   goto exit_p;  case NET_MEM:   printf("Memory error/n");   goto exit_p;  case NET_PARAM:   printf("Param error/n");   goto exit_p;  case NET_SOCK:   printf("Socket error/n");   goto exit_p;  default:break;  } exit_p:  return NET_ERROR; }  void usage(void) {  printf("Usage: Netlink -G <param>/n/t-S <param>/n"); }  int main(int argc, char **argv) {  netlink_sock h_sock;  char rbuf[1024];  char sbuf[1024];  int ret, type, slen = 0, rlen = 0;   ret = netlink_sock_init(&h_sock, HELLO_CMD, USER_NETLINK_CMD);  if(NET_OK != parse_ret(ret))   goto exit_p;   bzero(&rbuf, sizeof(rbuf));  bzero(&sbuf, sizeof(sbuf));  if(argc < 3)  {   usage();   goto exit_p;  }  if(!strncmp("-G", argv[1], 2))   type = HELLO_GET;  else if(!strncmp("-S", argv[1], 2))   type = HELLO_SET;   strcpy(sbuf, argv[2]);  slen = strlen(sbuf);  ret = netlink_send(&h_sock, type, sbuf, slen, rbuf, &rlen);  if(NET_OK != parse_ret(ret))   goto exit_p;   if(rlen > 0)  {   rbuf[rlen] = '/0';   printf("K rep [len = %d]:%s/n", rlen, rbuf);  }  printf("K[len = %d]: %s/n", rlen, rbuf);  exit_p:  netlink_sock_deinit(&h_sock);  return 0; } 

總結

以上就是本文關于linux下用戶程序同內核通信詳解(netlink機制)的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久婷婷国产麻豆91天堂| 国产精品福利网站| 欧美大奶子在线| 尤物yw午夜国产精品视频| 亚洲第一区第二区| 久久视频在线视频| 亚洲成在人线av| 91免费视频网站| 欧美电影免费播放| 欧美日韩在线视频一区| 亚洲自拍偷拍视频| 日韩电视剧在线观看免费网站| 久久精品国产久精国产思思| 国产精品自拍偷拍视频| 国产三级精品网站| 亚洲国产高潮在线观看| 在线精品视频视频中文字幕| 日韩欧美中文字幕在线观看| 精品久久久久久亚洲国产300| 国产精品一区专区欧美日韩| 4438全国亚洲精品在线观看视频| 亚洲qvod图片区电影| 国产日本欧美视频| 国产美女扒开尿口久久久| 亚洲一区二区三区毛片| 中文字幕一区二区精品| 欧美成人精品三级在线观看| 国产成人精品日本亚洲专区61| 一区二区中文字幕| 亚洲第一福利网| 日韩欧美极品在线观看| 欧美日韩一区二区三区| 亚洲第一页中文字幕| 欧美性少妇18aaaa视频| 日韩av在线免播放器| 亚洲精品一区二三区不卡| 97在线看免费观看视频在线观看| 国产日韩在线看| 91亚洲精品久久久| 亚洲影视九九影院在线观看| 一个色综合导航| 日韩精品免费看| 亚洲人成电影网站色| 久久久久久久久中文字幕| 亚洲国产一区二区三区在线观看| 久久精品国产一区| www.日韩免费| 欧美第一淫aaasss性| 国产一区深夜福利| 成人精品aaaa网站| 国内成人精品一区| 久久精品成人欧美大片古装| 国产日韩欧美中文在线播放| 亚洲欧美中文在线视频| 亚洲精品成人久久电影| 国产精品都在这里| 一区二区三区四区视频| 亚洲护士老师的毛茸茸最新章节| 亚洲精品久久视频| 国产欧美日韩中文| 日韩欧美国产网站| 久久久久久久影视| 欧美一区二区三区艳史| 亚洲精品国产美女| 91久久久久久久一区二区| 欧美精品成人在线| 国产情人节一区| 久久五月情影视| 中文字幕亚洲一区二区三区五十路| 欧美成人免费观看| 欧美激情女人20p| 尤物yw午夜国产精品视频明星| 日韩欧美精品中文字幕| 中文字幕日本欧美| 大胆人体色综合| 欧美日本精品在线| 久久精品成人一区二区三区| 日本电影亚洲天堂| 一个色综合导航| 国产一区视频在线| 久久久视频在线| 久久久久久久久电影| 成人黄色短视频在线观看| 最近2019中文免费高清视频观看www99| 九九久久国产精品| 久久久国产精彩视频美女艺术照福利| 国产精品网址在线| 欧美性极品少妇精品网站| 久久99热精品这里久久精品| 国产精品电影久久久久电影网| 欧美日韩亚洲91| 亚洲日韩中文字幕| 日韩在线观看免费高清完整版| 91av视频在线| 精品亚洲va在线va天堂资源站| 伊人久久大香线蕉av一区二区| 国产精品午夜一区二区欲梦| 日韩美女在线播放| 亚洲人成电影网站| 国产成人免费av电影| 欧美裸体xxxx极品少妇| 91高清免费视频| 2020欧美日韩在线视频| 欧美日韩免费观看中文| 国产日产久久高清欧美一区| 欧美日韩黄色大片| 色综合91久久精品中文字幕| 欧美高清不卡在线| 亚洲福利在线视频| 日韩国产精品一区| 欧美在线视频网站| 久久久久久久久久久av| 欧美精品久久一区二区| 成人午夜在线影院| 久久视频在线直播| xvideos国产精品| 久久免费视频这里只有精品| 亚洲a中文字幕| 久久久久亚洲精品成人网小说| 亚洲国产又黄又爽女人高潮的| 国产在线久久久| 日韩欧美国产成人| 亚洲国产精品久久久久| 国产精品香蕉国产| 日本久久亚洲电影| 亚洲欧美在线免费观看| 欧美一级黑人aaaaaaa做受| 中文字幕亚洲欧美在线| 91免费综合在线| 国产精品高精视频免费| 日韩精品在线视频| 欧美性xxxx极品高清hd直播| 亚洲免费精彩视频| 国产精品久久久久久久av电影| 日韩欧美一区二区三区| 亚洲国产古装精品网站| 日韩在线小视频| 91免费版网站入口| 日韩av理论片| 亚洲永久免费观看| 国产成人高清激情视频在线观看| 在线播放国产精品| 久久韩剧网电视剧| 国产精品久久久久7777婷婷| 中文字幕视频在线免费欧美日韩综合在线看| 黑人巨大精品欧美一区二区三区| 久久久久一本一区二区青青蜜月| 欧美激情第三页| 伊人久久免费视频| 91香蕉亚洲精品| 亚洲字幕一区二区| 久久在线精品视频| 狠狠久久亚洲欧美专区| 亚洲国产精品大全| 久久久免费观看| 人人做人人澡人人爽欧美| 精品视频中文字幕| 一级做a爰片久久毛片美女图片| 日韩在线欧美在线国产在线| 久久欧美在线电影| 国产精品久久久久久久久粉嫩av| 亚洲一区中文字幕| 亚洲韩国欧洲国产日产av| 97视频在线观看免费高清完整版在线观看|