linux 核心進程與使用者進程的通訊 方法一 使用sockopt與核心交換資料

來源:互聯網
上載者:User
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

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.