参考:http://bbs.driverdevelop.com/read.php?tid-101363.html
在2.6.16内核的netfilter中,netfilter一个重大修正思想就是将netfilter作为一个协议无关的框架,表现在内核结构树中单独建立net/netfilter目录,而在以前netfilter是附着在各个协议目录之下的,如在net/ipv4, net/ipv6等目录下。
内核2.6.18.8 的 linux/netfilter/x_tables.h 中定义了 struct xt_match :
1: struct xt_match
2: {
3: struct list_head list;
4:
5: const char name[XT_FUNCTION_MAXNAMELEN-1];
6:
7: /* Return true or false: return FALSE and set *hotdrop = 1 to
8: force immediate packet drop. */
9: /* Arguments changed since 2.6.9, as this must now handle
10: non-linear skb, using skb_header_pointer and
11: skb_ip_make_writable. */
12: int (*match)(const struct sk_buff *skb,
13: const struct net_device *in,
14: const struct net_device *out,
15: const struct xt_match *match,
16: const void *matchinfo,
17: int offset,
18: unsigned int protoff,
19: int *hotdrop);
20:
21: /* Called when user tries to insert an entry of this type. */
22: /* Should return true or false. */
23: int (*checkentry)(const char *tablename,
24: const void *ip,
25: const struct xt_match *match,
26: void *matchinfo,
27: unsigned int matchinfosize,
28: unsigned int hook_mask);
29:
30: /* Called when entry of this type deleted. */
31: void (*destroy)(const struct xt_match *match, void *matchinfo,
32: unsigned int matchinfosize);
33:
34: /* Called when userspace align differs from kernel space one */
35: int (*compat)(void *match, void **dstptr, int *size, int convert);
36:
37: /* Set this to THIS_MODULE if you are a module, otherwise NULL */
38: struct module *me;
39:
40: char *table;
41: unsigned int matchsize;
42: unsigned int hooks;
43: unsigned short proto;
44:
45: unsigned short family;
46: u_int8_t revision;
47: };
在进行实际匹配目标查找时会进行名字、协议族、表名、挂接点、协议等的比较,如匹配的检查:
(在使用iptables命令时,许多返回的错误类型可从这里看到。)
1: int xt_check_match(const struct xt_match *match, unsigned short family,
2: unsigned int size, const char *table, unsigned int hook_mask,
3: unsigned short proto, int inv_proto)
4: {
5: if (XT_ALIGN(match->matchsize) != size) {
6: printk("%s_tables: %s match: invalid size %Zu != %u/n",
7: xt_prefix[family], match->name,
8: XT_ALIGN(match->matchsize), size);
9: return -EINVAL;
10: }
11: if (match->table && strcmp(match->table, table)) {
12: printk("%s_tables: %s match: only valid in %s table, not %s/n",
13: xt_prefix[family], match->name, match->table, table);
14: return -EINVAL;
15: }
16: if (match->hooks && (hook_mask & ~match->hooks) != 0) {
17: printk("%s_tables: %s match: bad hook_mask %u/n",
18: xt_prefix[family], match->name, hook_mask);
19: return -EINVAL;
20: }
21: if (match->proto && (match->proto != proto || inv_proto)) {
22: printk("%s_tables: %s match: only valid for protocol %u/n",
23: xt_prefix[family], match->name, match->proto);
24: return -EINVAL;
25: }
26: return 0;
27: }