转自: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. Go Revel - Cache(缓存)

    revel在服务器端提供了`cache`库用以低延迟的存储临时数据.它缓存那些需要经常访问数据库但是变化不频繁的数据,也可以实现用户会话的存储. ##有效期 一下三种方法为缓存元素设置过期时间: 1. ...

  2. android——判断当前网络是否可用

    http://www.cnblogs.com/codeworker/archive/2012/04/23/2467180.html //判断当前是否有网络连接 private boolean isCo ...

  3. 【转】svn:is not under version control and is not part of the commit, yet its child解决办法

    来自:http://blog.csdn.net/lufeng20/article/details/7641093 在把写好的代码提交到svn上面时,遇到了一个错误如下: svn: Commit fai ...

  4. 《深入理解Java虚拟机》读书笔记:垃圾收集器与内存分配策略

    请移步至:http://zhanjindong.info/2014/05/18/java-gc/

  5. Path expected for join!错误处理

    在Hibernate中,进行连接查询时,如果使用join语句,就容易产生标题所示的错误. 比如from Content o left join Mcp mcp where o.mcp.id=mcp.i ...

  6. python mysql redis mongodb selneium requests二次封装为什么大都是使用类的原因,一点见解

    1.python mysql  redis mongodb selneium requests举得这5个库里面的主要被用户使用的东西全都是面向对象的,包括requests.get函数是里面每次都是实例 ...

  7. DES ECB 模式 JAVA PHP C# 实现 加密 解密 兼容

    版本一: JAVA: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sun.misc.BASE64Decoder; i ...

  8. html div+css做页面布局

    http://blog.csdn.net/mercop/article/details/7882000 HTML CSS + DIV实现整体布局 1.技术目标: 开发符合W3C标准的Web页面 理解盒 ...

  9. 128、View 绘制流程 & 自定义View

    记清楚函数调用的顺序才能准确地进行调用. 根据调用链,可将整个绘制过程分为三部分:Measure - Layout - Draw Measure 过程 1. 测量过程由上至下,在measure过程的最 ...

  10. VS2017 配置freeglut3.0.0

    配置freeglut: 1. 先下载cmake和freeglut3.0.0文件,并使用cmake编译freeglut,再使用vs2017生成解决方案,详细步骤见https://blog.csdn.ne ...