转自:http://blog.csdn.net/jk110333/article/details/8642261
 
用户态与内核态交互通信的方法不止一种,sockopt是比较方便的一个,写法也简单.
缺点就是使用 copy_from_user()/copy_to_user()完成内核和用户的通信, 效率其实不高, 多用在传递控制 选项 信息,不适合做大量的数据传输
 
用户态函数:
发送:int setsockopt ( int sockfd, int proto, int cmd, void *data, int datelen);
接收:int getsockopt(int sockfd, int proto, int cmd, void *data, int datalen)
第一个参数是socket描述符;
第二个参数proto是sock协议,IP RAW的就用SOL_SOCKET/SOL_IP等,TCP/UDP socket的可用SOL_SOCKET/SOL_IP/SOL_TCP/SOL_UDP等,即高层的socket是都可以使用低层socket的命令字 的,IPPROTO_IP;
第三个参数cmd是操作命令字,由自己定义;
第四个参数是数据缓冲区起始位置指针,set操作时是将缓冲区数据写入内核,get的时候是将内核中的数 据读入该缓冲区;
第五个参数数据长度
 
内核态函数
注册:nf_register_sockopt(struct nf_sockopt_ops *sockops)
解除:nf_unregister_sockopt(struct nf_sockopt_ops *sockops)
setsockopt():在内核调用kernel_setsockopt函数
 
结构体 nf_sockopt_ops test_sockops

static struct nf_sockopt_ops nso = { 
       .pf  = PF_INET,       // 协议族  
      .set_optmin = 常数,    // 定义最小set命令字  
       .set_optmax = 常数+N,  // 定义最大set命令字 
       .set  = recv_msg,   // 定义set处理函数 
       .get_optmin = 常数,    // 定义最小get命令字 
       .get_optmax = 常数+N,  // 定义最大get命令字 
       .get  = send_msg,   // 定义set处理函数 
};

其中命令字不能和内核已有的重复,宜大不宜小。命令字很重要,是用来做标识符的。而且用户态和内核态要定义的相同,
    #define SOCKET_OPS_BASE          128 
    #define SOCKET_OPS_SET       (SOCKET_OPS_BASE) 
    #define SOCKET_OPS_GET      (SOCKET_OPS_BASE)  
    #define SOCKET_OPS_MAX       (SOCKET_OPS_BASE + 1)

set/get处理函数是直接由用户空间的 set/getsockopt函数调用的。 setsockopt函数向内核写数据,用getsockopt向内核读数据。
另外set和get的处理函数的参数应该是这样的
int recv_msg(struct sock *sk, int cmd, void __user *user, unsigned int len)
int send_msg(struct sock *sk, int cmd, void __user *user, unsigned int *len)
 
附:

int kernel_setsockopt(struct socket *sock, int level, int optname,
char *optval, unsigned int optlen)
{
mm_segment_t oldfs = get_fs();
char __user *uoptval;
int err;

uoptval = (char __user __force *) optval;

set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
err = sock_setsockopt(sock, level, optname, uoptval, optlen);
else
err = sock->ops->setsockopt(sock, level, optname, uoptval,
optlen);
set_fs(oldfs);
return err;
}

如果用户态level == SOL_SOCKET时,那么直接调用socket层统一的接口:sock_setsockopt,在socket层处理了,就像我之前说的那样,无论哪种协议,都在一个函数里面处理。
如果level不是SOL_SOCKET(也就是level是SOL_TCP/SOL_UDP,IPPROTO_IP),那么调用各自协议栈初始化时指向的setsockopt函数,11行的:sock->ops->setsockopt,

内核态与用户态通信 之 sockopt的更多相关文章

  1. Linux 内核态与用户态通信 netlink

    参考资料: https://blog.csdn.net/zqixiao_09/article/details/77131283 https://www.cnblogs.com/lopnor/p/615 ...

  2. 在linux系统中实现各项监控的关键技术(2)--内核态与用户态进程之间的通信netlink

    Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来使用 ...

  3. linux内核态和用户态的信号量

    在Linux的内核态和用户态都有信号量,使用也不同,简单记录一下. 1> 内核信号量,由内核控制路径使用.内核信号量是struct semaphore类型的对象,它在中定义struct sema ...

  4. Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3

    一.现代操作系统的权限分离: 现代操作系统一般都至少分为内核态和用户态.一般应用程序通常运行于用户态,而当应用程序调用系统调用时候会执行内核代码,此时会处于内核态.一般的,应用程序是不能随便进入内核态 ...

  5. 操作系统基本概念(内核态与用户态、操作系统结构)-by sixleaves

    内核态与用户态(为什么存在这种机制.程序应处于哪个状态.如何判断当前所处状态.哪些功能需要内核态.如何实现这种机制) 1.首先我们应该思考清楚为什么会有内核态和用户态?(为什么存在这种机制) 因为计算 ...

  6. go语言学习--内核态和用户态(协程)

    go中的一个特点就是引入了相比于线程更加轻量级的协程(用户态的线程),那么什么是用户态和内核态呢? 一.什么是用户态和内核态 当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核 ...

  7. Linux内核态和用户态

    两张图说明Linux内核态和用户态之间的关系

  8. [OS] 内核态和用户态的区别

    http://blog.csdn.net/fatsandwich/article/details/2131707# http://jakielong.iteye.com/blog/771663 当一个 ...

  9. cpu与寄存器,内核态与用户态及如何切换

    cpu:相当于计算机的大脑负责运算和发送命令: 寄存器:寄存器是cpu当中的一个有限存储部件,cpu从内存调用数据时,寄存器会将从内存调用的数据进行更新在寄存器中以一个字或变量进行存储. 寄存器总共分 ...

  10. 【转】linux内核态和用户态的区别

    原文网址:http://www.mike.org.cn/articles/linux-kernel-mode-and-user-mode-distinction/ 内核态与用户态是操作系统的两种运行级 ...

随机推荐

  1. JVM 内部原理(六)— Java 字节码基础之一

    JVM 内部原理(六)- Java 字节码基础之一 介绍 版本:Java SE 7 为什么需要了解 Java 字节码? 无论你是一名 Java 开发者.架构师.CxO 还是智能手机的普通用户,Java ...

  2. SQL 逗号分隔将一行拆成多行

    and number<=len(a.KOrderID) and type=)=',')

  3. Git 重命名操作

    截至目前,Tome 和Jerry 都使用手动命令来编译自己的项目.Jerry 决定为他们的项目创建 Makefile,并给予适当的名称来命名“string.c” 文件. [jerry@CentOS p ...

  4. VMware 虚拟机安装OSX el capitan 11.12

    今天在虚拟机里装苹果OSX ,参考下文: http://wenku.baidu.com/link?url=eq6lxPfiGPcNbQiFiykJDgYDtdzG238P6_-T8IKxbKyDHX0 ...

  5. Linux CentOS 6.9 Minimal 编译 OpenJDK 7

    今天学习<深入理解Java虚拟机:JVM高级特性与最佳实践>一书,并动手在Linux系统上编译OpenJDK 7,初次搞不太顺利,特记录下编译操作细节. 一.前期准备 约定:工具默认安装目 ...

  6. 【Window 7】解决Win7远程桌面无法全屏的方法

    在Windows中有一项远程桌面功能,可以登录到其他电脑上进行远程控制,就像操纵本机一样,非常方便.但是最近发现用远程桌面登录过去时并不是全屏模式,而是窗口模式,老要拉滚动条,实在很不方便,今天还是到 ...

  7. Maven支撑下的War应用依赖另外一个WAR应用的解决方案

    最近在做项目中,用Maven管理项目间的依赖关系,遇到一个问题,快折腾死了,不过初步试出来一种解决方案.在此把问题及解决方案描述一下,以资共享.   问题描述:有两个项目A和B,Dynamic Web ...

  8. Win10系统安装过程小记

    1.网上下载ghost系统http://win10.jysmac.cn/win1064.html 2.使用系统自带的激活工具激活 3.到windows官网下载更新工具更新系统,重新安装https:// ...

  9. centos7上设置中文字符集

    author: headsen  chen date: 2019-03-14   09:00:31   Linux系统会默认使用英文字符集,不会安装中文字符集等其他字符. 公司内部文件服务器等需要中文 ...

  10. Scala断言

    断言:提供了一组断言函数以用作在代码中记录和动态检查不变量的方式. import scala.Predef._ def addNaturals(nats: List[Int]): Int = { // ...