免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3022 | 回复: 4
打印 上一主题 下一主题

[内核模块] netfilter 求救 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-21 11:11 |只看该作者 |倒序浏览
大家好,小弟最近学习netfilter遇到问题,希望CU的兄弟可以帮到我,先谢谢大家了。
先贴代码,原文可以在:http://hi.baidu.com/widebright/item/0c6c94b44e749c9619469784  看到
下面的代码仅仅在原文进行修改测试。
运行测试环境:rehl5.4  虚拟机  内核2.6.32
  1. /*
  2. * widebright.c
  3. *
  4. *  Created on: 2009-10-13
  5. *       Author: widebright
  6. */

  7. #include <linux/module.h>
  8. #include <linux/moduleparam.h>
  9. #include <linux/kernel.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/ip.h>
  12. #include <linux/tcp.h>
  13. #include <net/tcp.h>
  14. #include <net/udp.h>
  15. #include <linux/netfilter.h>
  16. #include <linux/netfilter_ipv4.h>
  17. #include <net/sock.h>

  18. #include <net/netfilter/nf_nat.h>
  19. #include <net/netfilter/nf_nat_helper.h>
  20. #include <net/netfilter/nf_nat_rule.h>
  21. #include <net/netfilter/nf_conntrack.h>
  22. #include <net/netfilter/nf_conntrack_helper.h>
  23. #include <net/netfilter/nf_conntrack_expect.h>

  24. MODULE_LICENSE("GPL"); //用了nf_conntrack_tcp_update 函数要用这个遵守GPL开放协议才能编译通

  25. typedef unsigned int   uint32;
  26. typedef unsigned char   uchar8;

  27. typedef struct app_detection_module_struct {
  28.         uint32 sport;
  29.         uint32 dport;
  30.         uint32 saddr;
  31.         uint32 daddr;
  32.        
  33.         uint32 plen;//the len not include ip header and (tcp/udp)header
  34.   uchar8* payload;//packet not include ip header and (tcp/udp)header
  35. } APP_DATA;



  36. static void hex_dump(const unsigned char *buf, size_t len) {
  37.      size_t i;

  38.      for (i = 0; i < len; i++) {
  39.           if (i && !(i % 16))
  40.                printk("\n");
  41.           printk("%02x ", *(buf + i));
  42.      }
  43.      printk("\n");
  44. }

  45. char * is_mp3_request(char * start) {
  46.      char data[4] = ".mp3";
  47.      char * i = start;

  48.      i += 4; //跳过 GET
  49.      while (*i != ' ' && *i != '\n')
  50.           i++; //查找网络地址最后的位置

  51.      if (*(int *) (i - 4) == *(int *) data)
  52.           return i;
  53.      else
  54.           return NULL;
  55. }

  56. unsigned int check_link_address(unsigned int hooknum, struct sk_buff *skb,
  57.           const struct net_device *in, const struct net_device *out, int(*okfn)(
  58.                     struct sk_buff *)) {
  59.     struct iphdr *iph = NULL;
  60.     struct tcphdr *tcph = NULL;
  61.     struct tcphdr *udph = NULL;
  62.     uint32 i = 0;
  63.     APP_DATA* app_data = NULL;
  64.          int oldlen, datalen;
  65.         struct rtable *rt = skb->rtable;
  66.     enum ip_conntrack_info ctinfo;
  67.     iph = ip_hdr(skb);
  68.    
  69.     app_data = (APP_DATA* )kmalloc(sizeof(APP_DATA), GFP_ATOMIC);
  70.     if(app_data == NULL)
  71.             return NF_ACCEPT;
  72.    
  73.     app_data->saddr = iph->saddr;
  74.     app_data->daddr = iph->daddr;
  75.        
  76.          //Note that the connection tracking subsystem
  77.      //is invoked after the raw table has been processed, but before the mangle table.
  78.      //所以下面 要指定.priority = NF_IP_PRI_MANGLE  nf_ct_get 才会返回有效的值
  79.      struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  80.        
  81.     if (iph->protocol == IPPROTO_TCP) {
  82.      tcph = (void *) iph + iph->ihl * 4;
  83.       
  84.      app_data->sport = ntohs(tcph->source);        //Src端口
  85.      app_data->dport = ntohs(tcph->dest);         //Dest端口
  86.      app_data->payload = (char*)iph+(iph->ihl*4) + tcph->doff*4;        //从data里面偏移出前面的ip包头和tcp包头
  87.      app_data->plen = ntohs(iph->tot_len)-(iph->ihl*4) - tcph->doff*4;        //TCP包长度
  88.       

  89.                   if(ntohs(app_data->dport) == 80)
  90.                   {
  91.                            printk("src: %u.%u.%u.%u:%u  <===> dst: %u.%u.%u.%u:%u \n",NIPQUAD(app_data->saddr),ntohs(app_data->sport),NIPQUAD(app_data->daddr),ntohs(app_data->dport));
  92.                return NF_ACCEPT;
  93.           }
  94.           // printk("tcp packet to : %u.%u.%u.%u:%u\n",NIPQUAD(daddr),ntohs(dport));
  95.           // printk("---------ip total len =%d--------\n", ntohs(iph->tot_len));
  96.           // printk("---------tcph->doff =%d--------\n", tcph->doff*4);

  97.           /*       skb_linearize - convert paged skb to linear one
  98.            *       If there is no free memory -ENOMEM is returned, otherwise zero
  99.            *       is returned and the old skb data released.
  100.            * 这一步很关键,否则后面根据 包头偏移计算出来payload 得到东西不是正确的包结构
  101.            *2.6内核需要这么做。  因为新的系统可能为了提高性能,一个网络包的内容是分成几个  fragments来保存的
  102.            *  这时 单单根据 skb->data得到的只是包的第一个 fragments的东西。我见到我系统上的就是tcp头部和 tcp的payload
  103.            *  是分开保存在不同的地方的。可能ip,tcp头部等是后面系统层才加上的,和应用程序的payload来源不一样,使用不同的fragments就
  104.            *  可以避免复制数据到新缓冲区的操作提高性能。skb_shinfo(skb)->nr_frags  属性指明了这个skb网络包里面包含了多少块 fragment了。
  105.            *  具体可以看  《Linux Device Drivers, 3rd Editio》一书的17.5.3. Scatter/Gather I/O小节
  106.            * 《Understanding_Linux_Network_Internals》 一书 Chapter 21. Internet Protocol Version 4 (IPv4): Transmission 一章有非常详细的介绍
  107.            *  下面使用的skb_linearize 函数则可以简单的把 多个的frag合并到一起了,我为了简单就用了它。
  108.            */
  109.                   
  110.                 /*
  111.           if (0 != skb_linearize(skb)) {
  112.                return NF_ACCEPT;
  113.           }
  114.                   */
  115.                   
  116.           // payload = (void *)tcph + tcph->doff*4; skb_linearize(skb) 调用之后,skb被重新构建了,之前的tcp指向的不是正确的地址了。
  117.           //payload = (void *) skb->data + 40; //我的机器上tcph->doff*4 + iph->ihl*4  等于40, 就是从data里面偏移出前面的ip包头和tcp包头
  118.           //tcp 包长度 ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4
  119.          
  120.           app_data->payload = (void *) skb->data + 40;
  121.               app_data->plen = ntohs(iph->tot_len)-(iph->ihl*4) - tcph->doff*4;       
  122.                   //hex_dump(app_data->payload ,app_data->plen);

  123.                   /*
  124.                   if((app_data->plen)<10)
  125.                   {
  126.                         //printk("plen <10\n");
  127.                         return 0;
  128.                   }
  129.                   */
  130.                   if(memcmp(app_data->payload, "GET ", 4) == 0)   
  131.                   {
  132.                            printk("%s\n", "HTTP GET FOUND");
  133.                char * head = is_mp3_request(app_data->payload);
  134.                if (head) {
  135.                           
  136.                                         printk("%s\n", head);
  137.                     //刚刚发现把 http://www.google.cn/1.mp3 改成    http://www.google.cn/1.%6D%70%33 就可以跳过网关的检测了,%6D%70%33 是mp3的html编码
  138.                
  139.                     //nf_nat_mangle_tcp_packet 是netfilter nat模块里面的导出函数,所以需要nat模块加载之后才能进行的。
  140.                     //如果你没有配置内核自动加载这个模块,好像执行一下“sudo iptables -t nat --list” 命令就会加载起来。
  141.                  if (ct && nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
  142.                                                  (char*) head - (char *)app_data->payload -3 , 3,
  143.                                                  (char *) "%6D%70%33", sizeof("%6D%70%33")-1 )) {
  144.                          printk("-----------------nf_nat_mangle_tcp_packet--------------------\n%20s\n",
  145.                                    app_data->payload);
  146.                          return NF_ACCEPT;
  147.                  }

  148.                //wineshark 抓包说明后续tcp包的序号依然不对,原因是修改后,tcp的需要加上 增加的字节,但系统不知道这个改变,所以下次还是用以前的 序号来发送数据,
  149.                //所以后面的包的序号就不对了. 在/net/ipv4/tcp_output.c 中的tcp_transmit_skb函数中,可以看到系统是如何填写这个数据的。但在hook的时候无法
  150.                //得到tcp层的信息,本来想一劳永逸的把初始序号改正确的但无法做到。只好hook没个包的时候都把序号改正过来了。
  151.                //nf_nat_mangle_tcp_packet修改tcp包后,会记录下需要调整的seq的序列(参考内核源代码/net/ipv4/netfilter/nf_nat_helper.c 文件爱你里面的
  152.                //adjust_tcp_sequence函数,他把需要调整的信息记录在两个 struct nf_nat_seq结构里面了。)但没有看到自动对后续的网络国包进行处理了。
  153.                //所以需要在另外的hook里面把标识出来的需要修复序号的包都,调用一下seq修复函数nf_nat_seq_adjust,把后面所有tcp包的seq都进行修复。
  154.                //这个工作如果你的修改导致包的长度改变的都需要作。conntrack模块里面会调用helper module的
  155.                //nf_nat_seq_adjust_hook函数来作这个工作的。参考 内核源代码的 /net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 中的ipv4_confirm函数
  156.                //但没看到调用nf_nat_seq_adjust 函数的地方,所以我自己又加了两个hook来捕获后续网络包,显示的调用nf_nat_seq_adjust 函数。
  157.                //nf_nat_seq_adjust 函数在net/ipv4/netfilter/nf_nat_helper.c 文件的里面有,但没有导出,所以我把他复制过来了,不过 注意不同的内核扳本有所不同
  158.                //如果编译有问题,就去把对应的内核源代码中的几个函数复制出来吧。


  159.                return NF_ACCEPT;

  160.                  //不用 nf_nat_mangle_tcp_packet 函数来修改感到话,虽然下面修改办法没有问题,但计算tcp校验和和序列号的结果不对。
  161.                     char *end = skb_put(skb, 9); //希望skb的buffer的容两可以继续在尾部加上9个字节的数据,不然这个会导致BUG()触发,http请求数据不会太大吧。
  162.                     //memmove(

  163.                     while (end > head) {
  164.                          end--;
  165.                          *(end + 9) = *end;
  166.                     }
  167.                     memcpy(head, "%6D%70%33", 9);

  168.                     /* fix IP hdr checksum information */
  169.                     ip_hdr(skb)->tot_len = htons(skb->len);
  170.                     ip_send_check(ip_hdr(skb));


  171.                     //计算校验和,参考内核源码 的net/ipv4/tcp_ipv4.c tcp_v4_send_check函数
  172.                     //和net/ipv4/netfilter/nf_nat_helper.c nf_nat_mangle_tcp_packet 函数
  173.                                  //和net/netfilter/xt_TCPMSS.c 的 tcpmss_mangle_packet 函数
  174.                     datalen = skb->len - iph->ihl * 4;
  175.                     oldlen = datalen - 9;
  176.                     if (skb->ip_summed != CHECKSUM_PARTIAL) {
  177.                          if (!(rt->rt_flags & RTCF_LOCAL) && skb->dev->features
  178.                                    & NETIF_F_V4_CSUM) {
  179.                               skb->ip_summed = CHECKSUM_PARTIAL;
  180.                               skb->csum_start = skb_headroom(skb)
  181.                                         + skb_network_offset(skb) + iph->ihl * 4;
  182.                               skb->csum_offset = offsetof(struct tcphdr, check);
  183.                               tcph->check = ~tcp_v4_check(datalen, iph->saddr,
  184.                                         iph->daddr, 0);
  185.                          } else {
  186.                               tcph->check = 0;
  187.                               tcph->check = tcp_v4_check(datalen, iph->saddr,
  188.                                         iph->daddr, csum_partial(tcph, datalen, 0));
  189.                          }
  190.                     } else
  191.                          inet_proto_csum_replace2(&tcph->check, skb, htons(oldlen),
  192.                                    htons(datalen), 1);


  193.                      printk("---------------------------------------\n%20s\n",
  194.                               app_data->payload);

  195.                }
  196.           }

  197.           return NF_ACCEPT;
  198.           //return NF_DROP; /*丢掉这个包*/
  199.      }
  200.          else
  201.          {
  202.           return NF_ACCEPT;/*这个包传给下一个hook函数  另有NF_QUEUE, it's queued. */
  203.      }
  204.          
  205.        
  206.     kfree(app_data);
  207.     app_data = NULL;
  208.    
  209.     return NF_ACCEPT;
  210. }


  211. //一下3个函数是内核源代码的net/ipv4/netfilter/nf_nat_helper.c 里面的,没有导出。需要找到对应的内核扳本的才能编译通过
  212. //在http://lxr.linux.no/  上看到2.6.31 和2.6.28用到的其他函数有点变化了。下面是

  213. /* Adjust one found SACK option including checksum correction */
  214. static void
  215. sack_adjust(struct sk_buff *skb,
  216.              struct tcphdr *tcph,
  217.              unsigned int sackoff,
  218.              unsigned int sackend,
  219.              struct nf_nat_seq *natseq)
  220. {
  221.          while (sackoff < sackend) {
  222.                  struct tcp_sack_block_wire *sack;
  223.                  __be32 new_start_seq, new_end_seq;

  224.                  sack = (void *)skb->data + sackoff;
  225.                  if (after(ntohl(sack->start_seq) - natseq->offset_before,
  226.                            natseq->correction_pos))
  227.                          new_start_seq = htonl(ntohl(sack->start_seq)
  228.                                          - natseq->offset_after);
  229.                  else
  230.                          new_start_seq = htonl(ntohl(sack->start_seq)
  231.                                          - natseq->offset_before);

  232.                  if (after(ntohl(sack->end_seq) - natseq->offset_before,
  233.                            natseq->correction_pos))
  234.                          new_end_seq = htonl(ntohl(sack->end_seq)
  235.                                        - natseq->offset_after);
  236.                  else
  237.                          new_end_seq = htonl(ntohl(sack->end_seq)
  238.                                        - natseq->offset_before);

  239.                  printk("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
  240.                           ntohl(sack->start_seq), new_start_seq,
  241.                           ntohl(sack->end_seq), new_end_seq);

  242.                  inet_proto_csum_replace4(&tcph->check, skb,
  243.                                           sack->start_seq, new_start_seq, 0);
  244.                  inet_proto_csum_replace4(&tcph->check, skb,
  245.                                           sack->end_seq, new_end_seq, 0);
  246.                  sack->start_seq = new_start_seq;
  247.                  sack->end_seq = new_end_seq;
  248.                  sackoff += sizeof(*sack);
  249.          }
  250. }

  251. /* TCP SACK sequence number adjustment */
  252. static inline unsigned int
  253. nf_nat_sack_adjust(struct sk_buff *skb,
  254.                     struct tcphdr *tcph,
  255.                     struct nf_conn *ct,
  256.                     enum ip_conntrack_info ctinfo)
  257. {
  258.          unsigned int dir, optoff, optend;
  259.          struct nf_conn_nat *nat = nfct_nat(ct);
  260.                 nat = nfct_nat(ct);
  261.                 if (!nat) {
  262.                           /* NAT module was loaded late. */
  263.                           if (nf_ct_is_confirmed(ct))
  264.                                           return NF_ACCEPT;
  265.                           nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
  266.                          if (nat == NULL) {
  267.                                         pr_debug("failed to add NAT extension\n");
  268.                                         return NF_ACCEPT;
  269.                         }
  270.                 }
  271.                  
  272.          optoff = ip_hdrlen(skb) + sizeof(struct tcphdr);
  273.          optend = ip_hdrlen(skb) + tcph->doff * 4;

  274.          if (!skb_make_writable(skb, optend))
  275.                  return 0;

  276.          dir = CTINFO2DIR(ctinfo);

  277.          while (optoff < optend) {
  278.                  /* Usually: option, length. */
  279.                  unsigned char *op = skb->data + optoff;

  280.                  switch (op[0]) {
  281.                  case TCPOPT_EOL:
  282.                          return 1;
  283.                  case TCPOPT_NOP:
  284.                          optoff++;
  285.                          continue;
  286.                  default:
  287.                          /* no partial options */
  288.                          if (optoff + 1 == optend ||
  289.                              optoff + op[1] > optend ||
  290.                              op[1] < 2)
  291.                                  return 0;
  292.                          if (op[0] == TCPOPT_SACK &&
  293.                              op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
  294.                              ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
  295.                                  sack_adjust(skb, tcph, optoff+2,
  296.                                              optoff+op[1], &nat->seq[!dir]);
  297.                          optoff += op[1];
  298.                  }
  299.          }
  300.          return 1;
  301. }





  302. /* TCP sequence number adjustment.  Returns 1 on success, 0 on failure */
  303. int
  304. nf_nat_seq_adjust(struct sk_buff *skb,
  305.                   struct nf_conn *ct,
  306.                   enum ip_conntrack_info ctinfo)
  307. {
  308.         struct tcphdr *tcph;
  309.         int dir;
  310.         __be32 newseq, newack;
  311.         s16 seqoff, ackoff;
  312.         struct nf_conn_nat *nat = nfct_nat(ct);
  313.         struct nf_nat_seq *this_way, *other_way;

  314.         dir = CTINFO2DIR(ctinfo);

  315.         this_way = &nat->seq[dir];
  316.         other_way = &nat->seq[!dir];

  317.         if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
  318.                 return 0;

  319.         tcph = (void *)skb->data + ip_hdrlen(skb);
  320.         if (after(ntohl(tcph->seq), this_way->correction_pos))
  321.                 seqoff = this_way->offset_after;
  322.         else
  323.                 seqoff = this_way->offset_before;

  324.         if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
  325.                   other_way->correction_pos))
  326.                 ackoff = other_way->offset_after;
  327.         else
  328.                 ackoff = other_way->offset_before;

  329.         newseq = htonl(ntohl(tcph->seq) + seqoff);
  330.         newack = htonl(ntohl(tcph->ack_seq) - ackoff);

  331.         inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
  332.         inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);

  333.         printk("Adjusting sequence number from %u->%u, ack from %u->%u\n",
  334.                  ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
  335.                  ntohl(newack));

  336.         tcph->seq = newseq;
  337.         tcph->ack_seq = newack;

  338.         return nf_nat_sack_adjust(skb, tcph, ct, ctinfo);
  339. }



  340. unsigned int fix_seq(unsigned int hooknum, struct sk_buff *skb,
  341.           const struct net_device *in, const struct net_device *out, int(*okfn)(
  342.                     struct sk_buff *))
  343. {


  344.      enum ip_conntrack_info ctinfo;

  345.      //Note that the connection tracking subsystem
  346.      //is invoked after the raw table has been processed, but before the mangle table.
  347.      //所以下面 要指定.priority = NF_IP_PRI_MANGLE  nf_ct_get 才会返回有效的值
  348.      struct nf_conn *ct = nf_ct_get(skb, &ctinfo);

  349.      //调用nf_nat_seq_adjust函数,修正nf_nat_mangle_tcp_packet 之后造成的tcp包的序列号不对问题
  350.      //这个需要在修改后的双向网络包上都要进行,所以需要hook双向的吧?,nf_nat_mangle_tcp_packet
  351.      //中调用了adjust_tcp_sequence知识记录下了应该作的修改。
  352.      //因为nf_nat_mangle_tcp_packet  给需要进行序号修正的conntrack加上IPS_SEQ_ADJUST_BIT标志了。
  353.      //所以这里判断是不是这个标志就进行修改。不知道这会不会和其他nat helper moudle冲突,如果别人也用这个
  354.      //标志时就可能出现重复修改等问题,因为里面的序号调整结构都是通用的。
  355.      //也许进行更细致的检查,比如给conntrack的ct结构加上 其他唯一的status标志比较好一点,
  356.      //反正就是要保证我们要修复序号的包是我们前面用nf_nat_mangle_tcp_packet
  357.      //修改过包内容的那个连接的,而不是其他的连接的包。
  358.      //写一个nat helper module来修改tcp包也许比在这种hook module里面进行修改更合适。去看看netfilter的文档看看。
  359.      //因为我确信自己系统  没有运行nat help module,所以为了简单就这样进行修改了,测试过没有什么问题。
  360.      //最好研究一下nat conntrack的那些代码,我也不是清楚具体的细节。

  361.      if (ct  &&  test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
  362.              && (ctinfo != IP_CT_RELATED + IP_CT_IS_REPLY)  ) {
  363.              nf_nat_seq_adjust(skb, ct, ctinfo);
  364.      }

  365.      return NF_ACCEPT;
  366.    
  367. }



  368. static struct nf_hook_ops http_hooks = { .pf = NFPROTO_IPV4, /*IPV4 协议的*/
  369.          .priority = NF_IP_PRI_MANGLE , // NF_IP_PRI_FIRST, //NF_IP_PRI_LAST ;NF_IP_PRI_NAT_SRC ;
  370.           .hooknum = NF_INET_LOCAL_OUT, /* NF_IP_LOCAL_OUT 我们只处理出去的网路包 */
  371.           .hook = check_link_address,
  372.           .owner = THIS_MODULE, };




  373. static struct nf_hook_ops  seq_adjust[] = {

  374.          {
  375.                  .hook            = fix_seq,
  376.                  .owner           = THIS_MODULE,
  377.                  .pf              = PF_INET,
  378.                  .hooknum         = NF_INET_POST_ROUTING,
  379.                  .priority        = NF_IP_PRI_MANGLE,//NF_IP_PRI_CONNTRACK_CONFIRM,
  380.          },
  381.          {
  382.                  .hook            = fix_seq,
  383.                  .owner           = THIS_MODULE,
  384.                  .pf              = PF_INET,
  385.                  .hooknum         = NF_INET_LOCAL_IN,
  386.                  .priority        = NF_IP_PRI_MANGLE,//NF_IP_PRI_CONNTRACK_CONFIRM,
  387.          },
  388. };


  389. static int __init widebright_init(void)
  390. {
  391.       int ret = 0;
  392.       ret = nf_register_hooks(seq_adjust,
  393.                                  ARRAY_SIZE(seq_adjust));

  394.          if (ret < 0) {
  395.             return ret;
  396.          }
  397.          printk("insert test.ko\n");
  398.      return nf_register_hook(&http_hooks);
  399.   
  400. }

  401. static void __exit widebright_cleanup(void)
  402. {
  403.      nf_unregister_hooks(seq_adjust,
  404.                                  ARRAY_SIZE(seq_adjust));
  405.      nf_unregister_hook(&http_hooks);
  406.         
  407.         printk("remove test.ko\n");
  408. }

  409. module_init(widebright_init);
  410. module_exit(widebright_cleanup);
复制代码
错误日志如下:
  1. HTTP GET FOUND
  2. HTTP/1.1
  3. Host: www.baidu.com
  4. User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.12) Gecko/2009070811 Red Hat/3.0.12-1.el5_3 Firefox/3.0.12
  5. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  6. Accept-Language: en-us,en;q=0.5
  7. Accept-Encoding: gzip,deflate
  8. Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
  9. Keep-Alive: 300
  10. Proxy-Connection: keep-alive
  11. Cookie: BAIDUID=1D0A4FC00A04363B537ED1730413ADB0:FG=1; BD_UPN=1333


  12. BUG: unable to handle kernel NULL pointer dereference at 00000044
  13. IP: [<f80a2178>] nf_nat_mangle_tcp_packet+0xeb/0x26f [nf_nat]
  14. *pde = 7f489067
  15. Oops: 0000 [#4] SMP
  16. last sysfs file: /sys/devices/pci0000:00/0000:00:11.0/0000:02:03.0/local_cpus
  17. Modules linked in: test iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 autofs4 lockd sunrpc ip_tables ip6_tables x_tables vmhgfs vsock vmmemctl acpiphp dm_mirror dm_multipath scsi_dh video output sbs sbshc battery ipv6 lp sg joydev snd_ens1371 gameport snd_rawmidi snd_ac97_codec ac97_bus snd_seq_dummy ac snd_seq_oss snd_seq_midi_event snd_seq tpm_tis snd_seq_device snd_pcm_oss snd_mixer_oss tpm snd_pcm serio_raw snd_timer tpm_bios i2c_piix4 button pcnet32 ide_cd_mod cdrom snd soundcore snd_page_alloc pcspkr floppy mii parport_pc i2c_core parport rtc_cmos rtc_core rtc_lib vmci vmxnet pvscsi vmxnet3 dm_region_hash dm_log dm_mod ata_piix libata mptspi mptscsih mptbase scsi_transport_spi sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd [last unloaded: test]

  18. Pid: 28685, comm: firefox Tainted: G      D    (2.6.32.63 #2) VMware Virtual Platform
  19. EIP: 0060:[<f80a2178>] EFLAGS: 00210246 CPU: 1
  20. EIP is at nf_nat_mangle_tcp_packet+0xeb/0x26f [nf_nat]
  21. EAX: 00000000 EBX: f6aa30c4 ECX: ffffbbc8 EDX: 654ade00
  22. ESI: f6b18134 EDI: 000001ff EBP: 0000020d ESP: f1d0db80
  23. DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
  24. Process firefox (pid: 28685, ti=f1d0d000 task=f40e0cc0 task.ti=f1d0d000)
  25. Stack:
  26. 00000014 00000000 f1e33464 f6aa30d8 f1e4acc0 00000000 0000001e f1daf90a
  27. <0> f4665200 f82f56d0 f82f55b4 0000001b 00000003 f82f56d4 00000009 f6b18134
  28. <0> 0000d14b f1daf8d8 f1e33464 00d0dc18 f82f5778 f1d0dc1c 00000003 f6b18134
  29. Call Trace:
  30. [<f82f55b4>] ? fix_seq+0x248/0x26c [test]
  31. [<c06282c4>] ? nf_iterate+0x30/0x61
  32. [<c0634318>] ? dst_output+0x0/0x7
  33. [<c0634318>] ? dst_output+0x0/0x7
  34. [<c0628487>] ? nf_hook_slow+0x41/0x99
  35. [<c0634318>] ? dst_output+0x0/0x7
  36. [<c0635567>] ? __ip_local_out+0x8b/0x91
  37. [<c0634318>] ? dst_output+0x0/0x7
  38. [<c0635575>] ? ip_local_out+0x8/0x17
  39. [<c0636059>] ? ip_queue_xmit+0x2e8/0x32c
  40. [<c04aaca0>] ? pollwake+0x0/0x56
  41. [<c0610648>] ? dev_hard_start_xmit+0x23b/0x2e7
  42. [<c061fa69>] ? sch_direct_xmit+0x6c/0x105
  43. [<c0648d7d>] ? tcp_v4_send_check+0x7a/0xb0
  44. [<c0644b37>] ? tcp_transmit_skb+0x56c/0x59f
  45. [<c0645dbe>] ? tcp_write_xmit+0x758/0x816
  46. [<c060a27b>] ? __alloc_skb+0x49/0x10c
  47. [<c0645e9a>] ? __tcp_push_pending_frames+0x1e/0x70
  48. [<c063c6e6>] ? tcp_sendmsg+0x7c8/0x8b6
  49. [<c06043b8>] ? sock_sendmsg+0xc7/0xe1
  50. [<c0441fd8>] ? autoremove_wake_function+0x0/0x2d
  51. [<c04aace9>] ? pollwake+0x49/0x56
  52. [<c04266ea>] ? default_wake_function+0x0/0x8
  53. [<c041f94b>] ? __wake_up_common+0x2e/0x58
  54. [<c0604d53>] ? sys_sendto+0x105/0x130
  55. [<c049e0fe>] ? do_sync_write+0xbf/0xfe
  56. [<c0441fd8>] ? autoremove_wake_function+0x0/0x2d
  57. [<c0604d97>] ? sys_send+0x19/0x1d
  58. [<c0605698>] ? sys_socketcall+0xda/0x1aa
  59. [<c0402804>] ? sysenter_do_call+0x12/0x22
  60. Code: 83 e0 0f 0f b6 c0 c1 e0 02 83 c4 0c 29 c7 88 d0 83 e0 0c 3c 0c 0f 84 c7 00 00 00 8b 44 24 10 83 b8 d4 00 00 00 00 78 72 8b 46 14 <f6> 40 44 0e 74 69 83 ca 0c 8b 8e a8 00 00 00 88 56 64 8b 96 94
  61. EIP: [<f80a2178>] nf_nat_mangle_tcp_packet+0xeb/0x26f [nf_nat] SS:ESP 0068:f1d0db80
  62. CR2: 0000000000000044
  63. ---[ end trace e586f0509fd5abb4 ]---
复制代码
我知道错误在nf_nat_mangle_tcp_packet,但是却不知道怎么处理,望CU的兄弟给与支持,先谢谢了。

论坛徽章:
0
2 [报告]
发表于 2014-08-21 11:34 |只看该作者
没有人会吗?自己顶一个。。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2014-08-21 12:52 |只看该作者
回复 1# jewson


BUG: unable to handle kernel NULL pointer dereference at 00000044
IP: [<f80a2178>] nf_nat_mangle_tcp_packet+0xeb/0x26f [nf_nat]


典型的 NULL pointer 解引用。


   

论坛徽章:
0
4 [报告]
发表于 2014-08-21 12:58 |只看该作者
是的,我知道是空指针错误,但不知道怎么解决?望Godbach指点

论坛徽章:
0
5 [报告]
发表于 2014-08-21 13:34 |只看该作者
是这个问题太基础了,还是?给位大哥帮帮忙啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP