nf_conn结构体为空?

本帖最后由 xtlx2000 于 2011-01-24 16:24 编辑

看了netfilter后练习了一个抓包程序,在FORWARD链抓的,钩子函数大概是
  1. 105 unsigned int hook_func(unsigned int hooknum,
  2. 106         struct sk_buff *skb,
  3. 107         const struct net_device *in,
  4. 108         const struct net_device *out,
  5. 109         int(*okfn)(struct sk_buff *))
  6. 110 {
  7. 111     struct sk_buff *sb = skb;
  8. 112     struct iphdr *iph;
  9. 113     struct nf_conn *ct = NULL;
  10. 114     enum ip_conntrack_info ctinfo;
  11. 115
  12. ....
  13. 118     ct = nf_ct_get(sb, &ctinfo);

  14. ...
  15. 131     curr->daddr = ct->tuplehash[dir].tuple.dst.u3.ip;
复制代码
抓包时有个别包会出现内核崩溃:
下载 (85.46 KB)
kernel崩溃
2011-01-24 16:22


查了下原来是有个别包获得的ct = nf_ct_get(sb, &ctinfo)为空,所以访问ct元素会内核崩溃,但我是在FORWARD抓的ftp协议包,skb怎么可能没有ct跟踪?(我还想根据ct来显示NAT信息),请问这是什么原因呢?该如何解决?谢谢

作者: xtlx2000   发布时间: 2011-01-24

确认一下内核是否启用了 NF_CONNTRACK. 另外,先不要测试 ftp 的 ct,测试一个普通链接,比如 80 端口的。

对于指针,读取之前先判断一下非空。

作者: Godbach   发布时间: 2011-01-24

本帖最后由 xtlx2000 于 2011-01-24 16:52 编辑

回复 Godbach


    大多数包都正常,也就是说ct!=NULL,即是开启的,但个别包获取的ct==NULL,这样内核就崩溃了,刚刚加了个if(!ct) return NF_ACCEPT;有了ct==NULL的包内核倒是不再崩溃了,但ftp客户端的ls命令后收不到“226 OK!”这条控制信息了?客户端卡在这里了。囧
这是我的hook函数,我只是从内核提取信息,并没有对内核结构体或skb做什么修改啊?晕了
  1. unsigned int hook_func(unsigned int hooknum,
  2.         struct sk_buff *skb,
  3.         const struct net_device *in,
  4.         const struct net_device *out,
  5.         int(*okfn)(struct sk_buff *))
  6. {
  7.     struct sk_buff *sb = skb;
  8.     struct iphdr *iph;
  9.     struct nf_conn *ct = NULL;
  10.     enum ip_conntrack_info ctinfo;

  11.     iph = ip_hdr(sb);
  12.     tot_len = ntohs(iph->tot_len);
  13.     ct = nf_ct_get(sb, &ctinfo);
  14.     if(!ct){
  15.         printk("No ct!\n");
  16.         return NF_ACCEPT;
  17.     }   
  18.     enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);

  19.     curr = kmalloc(sizeof(struct packet_info) + tot_len, GFP_KERNEL);
  20.     memset(curr, 0, sizeof(struct packet_info) + tot_len);

  21.     curr->number = number++;
  22.     curr->tot_len = tot_len;

  23.     //--------------------------------------------
  24.     if(ct){
  25.         /* daddr */
  26.         curr->daddr = ct->tuplehash[dir].tuple.dst.u3.ip;
  27.         /* if DNAT, we set nat_daddr */
  28.         if(iph->daddr != ct->tuplehash[dir].tuple.dst.u3.ip){
  29.             curr->nat_daddr = ct->tuplehash[!dir].tuple.src.u3.ip;
  30.         }   
  31.         /* saddr */
  32.         curr->saddr = ct->tuplehash[dir].tuple.src.u3.ip;
  33.         /* if SNAT, we set nat_saddr */
  34.         if(iph->saddr != ct->tuplehash[dir].tuple.src.u3.ip){
  35.             curr->nat_saddr = ct->tuplehash[!dir].tuple.dst.u3.ip;
  36.         }   
  37.     }   

  38.     curr->protocol = iph->protocol;
  39.     //--------------------------------------------

  40.     /* rtable */
  41.     curr->rt_dst = sb->rtable->rt_dst;
  42.     curr->rt_gateway = sb->rtable->rt_gateway;

  43.     if(tot_len){
  44.         memcpy(curr->data, iph, tot_len);
  45.     }   

  46.     /* send message to user */
  47.     sendnlmsg(curr);
  48.     printk("send OK!number=%d\n", curr->number);
  49.     kfree(curr);
  50.     curr = NULL;

  51.     return NF_ACCEPT;
  52. }
复制代码

作者: xtlx2000   发布时间: 2011-01-24



QUOTE:
# unsigned int hook_func(unsigned int hooknum,
#         struct sk_buff *skb,
#         const struct net_device *in,
#         const struct net_device *out,
#         int(*okfn)(struct sk_buff *))
# {
#     struct sk_buff *sb = skb;
#     struct iphdr *iph;
#     struct nf_conn *ct = NULL;
#     enum ip_conntrack_info ctinfo;
#

#     iph = ip_hdr(sb);
#     tot_len = ntohs(iph->tot_len);
#     ct = nf_ct_get(sb, &ctinfo);
#     if(!ct){
#         printk("No ct!\n");
#         return NF_ACCEPT;
#     }   
#     enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
#

#     curr = kmalloc(sizeof(struct packet_info) + tot_len, GFP_KERNEL);


这两行红色代码,你是不是用的全局变量。curr 是你自己定义的结构体吗。
为了便于定位问题,建议先暂时不要申请内存和sendmsg,只是读取一下 ct 的结果,通过内核 printk 信息出来。调试没问题了,再加其他功能。

作者: Godbach   发布时间: 2011-01-24

回复 Godbach


    虽然没找到啥原因,重写了一遍就好了,谢谢版主!

作者: xtlx2000   发布时间: 2011-01-24