自己写 Netfilter 匹配器[3]

[入库:2006年2月23日] [更新:2007年3月24日]

本文简介:

果取反标志 '!' 是否存在,如果有的话,在 'info->flags' 中写相应的值。
之后调用为这个骨架程序所写的内部函数 'parse_ipaddr' 来把 IP 地址从字符串转化为 32 位值。

         if (invert)
info->flags |= IPADDR_SRC_INV;

parse_ipaddr(argv[optind-1], &info->ipaddr.src);
break;
同样考虑,我们检查是否存在多次设置,置恰当的标志。
      case '2':
if (*flags & IPADDR_DST)
exit_error(PARAMETER_PROBLEM, "ipt_ipaddr: Only use --ipdst once!");
*flags |= IPADDR_DST;
info->flags |= IPADDR_DST;
if (invert)
info->flags |= IPADDR_DST_INV;

parse_ipaddr(argv[optind-1], &info->ipaddr.dst);
break;

default:
return 0;
}

return 1;
}
 

1.2.6 options 结构

前文中,我们已经谈到了要将每个参数映射到一个值。 'struct option' 就是一个达到这个目的的好办法。要想得到关于这个结构的进一步信息,强烈建议阅读 'man 3 getopt'。
static struct option opts[] = {
{ .name = "ipsrc", .has_arg = 1, .flag = 0, .val = '1' },
{ .name = "ipdst", .has_arg = 1, .flag = 0, .val = '2' },
{ .name = 0 }
};

 

1.2.7 init 函数

init 函数用于初始化一些特定的东西,比如 netfilter 的 cache 系统。现在不必过多考虑这个函数的具体用途。
static void init(struct ipt_entry_match *m, unsigned int *nfcache)
{
/* Can't cache this */
*nfcache |= NFC_UNKNOWN;
}

 

1.2.7 help 函数

这个函数通过 'iptables -m match_name -h' 被调用,用于显示可用的参数。
static void help(void)
{
printf (
"IPADDR v%s options:\n"
"[!] --ipsrc \t\t The incoming ip addr matches.\n"
"[!] --ipdst \t\t The outgoing ip addr matches.\n"
"\n", IPTABLES_VERSION
);
}

 

1.2.8 头文件 'ipt_ipaddr.h'

这个文件定义了我们需要的一些东西。
#ifndef _IPT_IPADDR_H
#define _IPT_IPADDR_H
我们已经在上文中使用了这些特定的值了。
#define IPADDR_SRC   0x01     /* Match source IP addr */
#define IPADDR_DST 0x02 /* Match destination IP addr */

#define IPADDR_SRC_INV 0x10 /* Negate the condition */
#define IPADDR_DST_INV 0x20 /* Negate the condition */
结构 'ipt_ipaddr_info' 是将要被拷贝到核心态程序的那个数据结构。
struct ipt_ipaddr {
u_int32_t src, dst;
};

struct ipt_ipaddr_info {

struct ipt_ipaddr ipaddr;

/* Flags from above */
u_int8_t flags;

};

#endif
 

1.3 第一章小结

第一部分中,我们讨论了 iptables 库的作用。我们记述了每个函数的内容和 'ipt_ipaddr_info' 这个用于保存信息的将要被拷贝到核心态程序来做进一步处理的重要结构。我们也看到了 iptables 结构和如何注册一个新的库。
应该注意,这仅仅是一个用于演示框架如何工作的骨架程序。而且,'ipt_ipaddr_info' 和其他类似的东西并不是 iptables/netfilter 的一部分,而仅仅是这个例子的一部分。  

2.0 netfilter 模块

一个匹配模块的工作就是察看每一个收到的包并决定是否符合某个判决准则。这个模块要做如下工作:
  • 接收每个包,并察看匹配模块相关的表
  • 告知 netfilter,我们的模块是否匹配上了这个包
 

2.1 可用的函数与数据结构

首先是一些基本数据结构,这些数据结构定义在 <linux/netfilter_ipv4/ip_tables.h>。
如果你对这个结构以及前面的 iptables 部分还有兴趣的话,你可以看看 Rusty Russell 和 Harald Welte 写的 netfilter hacking howto
struct ipt_match
{
struct list_head list;

const char name[IPT_FUNCTION_MAXNAMELEN];

/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
/* Arguments changed since 2.4, as this must now handle
non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
int (*match)(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
int *hotdrop);

/* Called when user tries to insert an entry of this type. */
/* Should return true or false. */
int (*checkentry)(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask);

/* Called when entry of this type deleted. */
void (*destroy)(void *matchinfo, unsigned int matchinfosize);

/* Set this to THIS_MODULE. */
struct module *me;
};
 

2.2 深入骨架程序

 

2.2.1 初始化

首先,我们初始化 'ipt_match' 数据结构中的常用域。

本文关键:自己写 Netfilter 匹配器
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top