Chinaunix首页 | 论坛 | 博客
  • 博客访问: 125734
  • 博文数量: 42
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 354
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-01 15:34
个人简介

不晓得说啥子

文章分类

全部博文(42)

文章存档

2015年(41)

2014年(1)

我的朋友

分类: LINUX

2015-04-21 10:33:03

内核空间的 netfilter与用户态的 iptables数据交互是通过 getsockopt()和setsockopt ()两个函数来完成的,这两个函数用来控制相关 socket文件描述符的选项值, 两个函数的原型:

int setsockopt( int sockfd,  int level, int optname, void *optval, socklen_t optlen);

int getsockopt( int sockfd, int level, int optname, void *optval, socklen_t optlen);

两个函数的具体细节这里不阐述。



新的命令字:

iptables通过扩充新的命令指端来实现特殊应用程序的内核与用户空间的数据交流,内核实现新的 sockopt命令字有两类,一类是添加完整的新的 level后引入,一类是在原有命令的基础上增加新的命令字。 netfilter就是在原有命令的基础上进行扩展,是先了内核的 netfilter与用户态的 iptables之间的数据交互。 Netfilter新加的命令字如下:

setsockopt 新加的命令字:

#define IPT_SO_SET_REPLACE                   重新设置规则
#define IPT_SO_ADD_COUNTERS             加入计数器

getsockopt新加的命令字:

#define IPT_SO_GET_INFO                         获取ipt_info
#define IPT_SO_GET_ENTRIES                     获取规则
#define IPT_SO_GET_REVISION_MATCH     获取match
#define IPT_SO_GET_REVISION_TARGET       获取target


新的调用流程:

为了支持新增加的关键字,需要在内核中作相应的改变,先来看一个常规的 setsockopt的调用流程:
setsockopt--> 系统调用 -->sys_socketcall->sys_setsockopt->sock_setsockopt->raw_setsockopt->ip_setsockopt
所有做的改变在于,在 ip_setsockopt调用时,如果发现是一个没有定义的协议,并且判断现在这个 opt是否为netfilter 所设置,如果是则调用 netfilter所设置的特殊处理函数,于是加入 netfiltersockopt 特殊处理后,新的流程如下:
sys_socketcall->sys_setsockopt->sock_setsockopt->raw_setsockopt->ip_setsockopt->nf_setsockopt

进入 netfilter后的处理流程如下:
nf_setsockopt-> nf_sockopt->  调用nf_sockopt_ops相应的 getset 操作
netfilter 中将nf_sockopt_ops setget 操作设置成如下两个函数,根据不同的命令再调用具体的处理函数



netfilter首先定义一些特殊的sockopt的操作,并将其注册到一个全局变量,如果发现有netfilteropt的操作,就调用这些特殊的操作,每个netfiltersockopt操作的结构如下:
struct nf_sockopt_ops
{
       struct list_head list;
       int pf;// 协议族
       
       int set_optmin;
       int set_optmax;
       int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len);//set函数
       int (*compat_set)(struct sock *sk, int optval,
                     void __user *user, unsigned int len);
 
       int get_optmin;
       int get_optmax;
       int (*get)(struct sock *sk, int optval, void __user *user, int *len);//get函数
       int (*compat_get)(struct sock *sk, int optval,
                     void __user *user, int *len);
       struct module *owner;
};
阅读(3289) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~