2.4和2.6内核的netfilter差异点

newdye 2011-01-10

本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。

msn:[email protected]

来源:http://yfydz.cublog.cn

1. 前言
 
在2.4和2.6内核中的netfilter基本框架都是相同的,只是在某些细节上有点差异,要移植的话主要看基本的数据结构和函数定义是否有变化,本文比较一下哪些数据结构和函数进行了修改。
 
以下比较用的是2.4.26和2.6.8.1。

2. ip_conntrack.h
 
描述连接的结构struct ip_conntrack相同,在2.6.8.1中增加了两个宏定义:
/* eg. PROVIDES_CONNTRACK(ftp); */
#define PROVIDES_CONNTRACK(name)                        \
        int needs_ip_conntrack_##name;                  \
        EXPORT_SYMBOL(needs_ip_conntrack_##name)
/*. eg. NEEDS_CONNTRACK(ftp); */
#define NEEDS_CONNTRACK(name)                                           \
        extern int needs_ip_conntrack_##name;                           \
        static int *need_ip_conntrack_##name __attribute_used__ = &needs_ip_conntrack_##name

3. ip_conntrack_helper.h
 
在struct ip_conntrack_helper结构中,成员函数help()的参数定义有所改变:
 
in 2.4.26:
 int (*help)(const struct iphdr *, size_t len,
      struct ip_conntrack *ct,
      enum ip_conntrack_info conntrackinfo);
 
in 2.6.8.1
 int (*help)(struct sk_buff *skb,
      struct ip_conntrack *ct,
      enum ip_conntrack_info conntrackinfo);
 
在2.4中参数是IP头指针和IP包长,在2.6中只用struct sk_buff了,这两个参数都可以提取出:
iphdr = skb->nh.iph;
len = skb->len;
 
另外函数ip_conntrack_expect_related()的参数位置在2.4和2.6中颠倒了:
 
in 2.4.26
extern int ip_conntrack_expect_related(struct ip_conntrack *related_to,
           struct ip_conntrack_expect *exp);
 
in 2.6.8.1
extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp,
           struct ip_conntrack *related_to);
 
这些改变导致多连接协议(ftp/irc/amanda等)的跟踪函数需要修改。
 
在2.6.8.1中增加了一个新函数:
/* Allocate space for an expectation: this is mandatory before calling
   ip_conntrack_expect_related. */
extern struct ip_conntrack_expect *ip_conntrack_expect_alloc(void);

4. ip_nat.h

基本相同,2.6中去掉了以下宏定义:
/* 2.3.19 (I hope) will define this in linux/netfilter_ipv4.h. */
#ifndef SO_ORIGINAL_DST
#define SO_ORIGINAL_DST 80
#endif

5. ip_nat_helper.h

在2.6.8.1中没有了以下的宏定义:
/* Standalone NAT helper, without a conntrack part */
#define IP_NAT_HELPER_F_STANDALONE 0x02

在2.6.8.1中没有了以下的函数定义:
extern void ip_nat_delete_sack(struct sk_buff *skb);

6. ip_conntrack_protocol.h
 
在结构struct ip_conntrack_protocol中多个结构函数参数发生变化:
in 2.4.26
 /* Try to fill in the third arg; return true if possible. */
 int (*pkt_to_tuple)(const void *datah, size_t datalen,
       struct ip_conntrack_tuple *tuple);
 
 /* Returns verdict for packet, or -1 for invalid. */
 int (*packet)(struct ip_conntrack *conntrack,
        struct iphdr *iph, size_t len,
        enum ip_conntrack_info ctinfo);
 /* Called when a new connection for this protocol found;
  * returns TRUE if it's OK.  If so, packet() called next. */
 int (*new)(struct ip_conntrack *conntrack, struct iphdr *iph,
     size_t len);
 /* Has to decide if a expectation matches one packet or not */
 int (*exp_matches_pkt)(struct ip_conntrack_expect *exp,
          struct sk_buff **pskb);
 
in 2.6.8.1
 int (*pkt_to_tuple)(const struct sk_buff *skb,
      unsigned int dataoff,
      struct ip_conntrack_tuple *tuple);
 /* Returns verdict for packet, or -1 for invalid. */
 int (*packet)(struct ip_conntrack *conntrack,
        const struct sk_buff *skb,
        enum ip_conntrack_info ctinfo);
 /* Called when a new connection for this protocol found;
  * returns TRUE if it's OK.  If so, packet() called next. */
 int (*new)(struct ip_conntrack *conntrack, const struct sk_buff *skb);
 /* Has to decide if a expectation matches one packet or not */
 int (*exp_matches_pkt)(struct ip_conntrack_expect *exp,
          const struct sk_buff *skb);
 
总的看,差别就是直接将数据包指针struct sk_buff传递到函数,而不是具体的数据头指针和长度,这些都由函数自己从数据包中解析。
这些改变导致每个IP上层协议(TCP/UDP/ICMP)跟踪的相关函数需要修改。

7. ip_nat_protocol.h
 
在结构struct ip_nat_protocol中manip_pkt()结构函数参数发生变化:

in 2.4.26
 /* Do a packet translation according to the ip_nat_proto_manip
  * and manip type. */
 void (*manip_pkt)(struct iphdr *iph, size_t len,
     const struct ip_conntrack_manip *manip,
     enum ip_nat_manip_type maniptype);

in 2.6.8.1
 /* Do a packet translation according to the ip_nat_proto_manip
  * and manip type.  Return true if succeeded. */
 int (*manip_pkt)(struct sk_buff **pskb,
    unsigned int hdroff,
    const struct ip_conntrack_manip *manip,
    enum ip_nat_manip_type maniptype);

差别就是直接将数据包指针struct sk_buff传递到函数,而不是具体的数据头指针和长度,这些都由函数自己从数据包中解析。
这些改变导致每个IP上层协议(TCP/UDP/ICMP)NAT的相关函数需要修改。

8. ip_tables.h
 
在struct ipt_match中的match()结构函数参数有所改变:
in 2.4.26
 int (*match)(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
       int offset,
       const void *hdr,
       u_int16_t datalen,
       int *hotdrop);

in 2.6.8.1
 int (*match)(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
       int offset,
       int *hotdrop);

在2.6中去掉了数据头和数据长度参数,这些都可以通过struct sk_buff *skb参数获取。这个改变导致所有匹配模块的match()函数需要修改。

在struct ipt_target中的参数倒是没有改变,但结构函数顺序发生了改变,这导致不是通过“.name = function”方式定义的所有目标模块结构参数顺序需要修改。

9. ip_conntrack_core.h
 
一个常用函数get_tuple()参数发生了变化:
 
in 2.4.26
extern int get_tuple(const struct iphdr *iph, size_t len,
       struct ip_conntrack_tuple *tuple,
       struct ip_conntrack_protocol *protocol);

in 2.6.8.1
extern int get_tuple(const struct iphdr *iph,
       const struct sk_buff *skb,
       unsigned int dataoff,
       struct ip_conntrack_tuple *tuple,
       const struct ip_conntrack_protocol *protocol);

2.8 ip_nat_core.h
 
函数icmp_reply_translation()的参数稍有改变:
 
in 2.4.26
extern unsigned int icmp_reply_translation(struct sk_buff *skb,
        struct ip_conntrack *conntrack,
        unsigned int hooknum,
        int dir);
 
in 2.6.8.1
extern int icmp_reply_translation(struct sk_buff **pskb,
      struct ip_conntrack *conntrack,
      unsigned int hooknum,
      int dir);
 

10. 结论
 
netfilter从2.4到2.6更新得不多,2.4下的模块只需要少量修改就可以在2.6中使用。

相关推荐