免费注册 查看新帖 |

Chinaunix

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

[网络子系统] 有关dev_queue_xmit函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-04-10 22:23 |只看该作者 |倒序浏览
本帖最后由 lawrence2013 于 2013-04-11 22:25 编辑

我想把从netfilter的LOCAL_OUT钩住的数据直接用dev_queue_xmit发出去,但似乎数据发不出去,请你们帮我看下我的代码哪里出问题?谢谢!

static struct nf_hook_ops modify_ops;

static unsigned int modify(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* nskb;
        struct iphdr* nip_hdr;
        unsigned int   nip_hdr_off;
        struct tcphdr* ntcp_hdr;
        unsigned int ntcp_hdr_off;
        struct icmphdr *icmph = NULL;
        int ret = 0;
        struct net *net = NULL;
   
        nskb = skb_copy(skb, GFP_ATOMIC);
        if(nskb == NULL)
        {
                     printk("%s\n", "skb_copy return NULL");
                     return NF_ACCEPT;
        }
   
   
        if( ip_hdr(nskb)->protocol != IPPROTO_ICMP)
       {
                    kfree_skb(nskb);
                    return NF_ACCEPT;
       }

        nip_hdr = ip_hdr(nskb);   //nip_hdr = nskb->nh.iph;
        nip_hdr_off = nip_hdr->ihl << 2;
   
        nip_hdr->daddr = in_aton("192.168.1.1");
        nip_hdr->check = 0;
        nip_hdr->check = ip_fast_csum((unsigned char *)nip_hdr, nip_hdr->ihl);

        icmph = icmp_hdr(nskb);
        icmph->checksum = 0;
        icmph->checksum = in_cksum((unsigned short *)icmph,
                            ntohs(nip_hdr->tot_len) - sizeof(struct iphdr));
   
        nskb->csum = 0;
        nskb->csum = csum_partial((unsigned char *)(ntcp_hdr + ntcp_hdr_off),
                                          ntohs(nip_hdr->tot_len) -
                                          nip_hdr_off - ntcp_hdr_off, 0);
        nskb->ip_summed = CHECKSUM_NONE;
        nskb->pkt_type  = PACKET_OUTGOING; //PACKET_OTHERHOST;

        neth_hdr = (struct ethhdr *) skb_push(nskb, ETH_HLEN);
        skb_reset_mac_header(nskb);
        nskb->protocol = neth_hdr->h_proto = htons(ETH_P_IP);
        memcpy (neth_hdr->h_dest, DMAC, ETH_ALEN);
        memcpy (neth_hdr->h_source, SMAC, ETH_ALEN);

        nskb->dev = dev_get_by_name(&init_net,ETH);
        if(nskb->dev==NULL)
        {
                printk("%s\n", "dev_get_by_name return NULL");
                kfree_skb(nskb);
                return NF_ACCEPT;
        }

        dev_hold(nskb->dev);
        printk("%s\n", "dev_hold ok");
        dev_put(nskb->dev);

        ret = dev_queue_xmit(nskb);
        printk("ret:%d\n", ret);
        return NF_STOLEN;

    }


    static int __init init(void)
    {
      int  ret = 0;
      modify_ops.hook = modify;
      modify_ops.hooknum = 3; //NF_IP_LOCAL_OUT;
      modify_ops.pf = PF_INET;
      modify_ops.priority = NF_IP_PRI_FIRST;

      ret = nf_register_hook(&modify_ops);
      if (ret < 0)
       {
         printk("%s\n", "can't modify skb hook!");
         return ret;
       }

        printk("%s\n", "insmod modify skb module");
        return 0;
    }

    static void __exit fini(void)
    {
        nf_unregister_hook(&modify_ops);
        printk("%s\n", "remove modify skb module.");
    }

    module_init(init);
    module_exit(fini);

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
2 [报告]
发表于 2013-04-11 08:13 |只看该作者
回复 1# lawrence2013

static struct nf_hook_ops modify_ops;




    static unsigned int modify(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* nskb;
        struct iphdr* nip_hdr;
        unsigned int   nip_hdr_off;
        struct tcphdr* ntcp_hdr;
        unsigned int ntcp_hdr_off;
        int ret = 0;
        struct net *net = NULL;
        nskb = skb_copy(skb, GFP_ATOMIC);
        if(nskb == NULL)
        {
                 printk("%s\n", "skb_copy return NULL");
                 return NF_ACCEPT;
        }
        if( ip_hdr(nskb)->protocol != IPPROTO_ICMP)
        {
                kfree_skb(nskb);
                return NF_ACCEPT;
        }
       nip_hdr这个变量在那里赋值的?
        nip_hdr->daddr = in_aton("166.111.4.100");
        nip_hdr->check = 0;
        nip_hdr->check = ip_fast_csum((unsigned char *)nip_hdr, nip_hdr->ihl);
        nskb->csum = 0;
        nskb->csum = csum_partial((unsigned char *)(ntcp_hdr + ntcp_hdr_off),
                                          ntohs(nip_hdr->tot_len) -
        nip_hdr_off - ntcp_hdr_off, 0);
        nskb->ip_summed = CHECKSUM_NONE;
        nskb->pkt_type  = PACKET_OUTGOING; //PACKET_OTHERHOST;
        
        你在这里操作skb干什么,你要发送的是nskb。到处都是这种基本的编码错误,懒得看了。。。
        neth_hdr = (struct ethhdr *) skb_push(skb, ETH_HLEN);
        skb_reset_mac_header(skb);
        skb->protocol = neth_hdr->h_proto = htons(ETH_P_IP);
        memcpy (neth_hdr->h_dest, DMAC, ETH_ALEN);
        memcpy (neth_hdr->h_source, SMAC, ETH_ALEN);
        nskb->dev = dev_get_by_name(&init_net,ETH);
        if(nskb->dev==NULL)
        {
                printk("%s\n", "dev_get_by_name return NULL");
                kfree_skb(nskb);
                return NF_ACCEPT;
        }
        dev_hold(nskb->dev);
        printk("%s\n", "dev_hold ok");
        dev_put(nskb->dev);
        ret = dev_queue_xmit(nskb);
        printk("ret:%d\n", ret);
        return NF_STOLEN;
    }

论坛徽章:
0
3 [报告]
发表于 2013-04-11 15:33 |只看该作者
这个代码是我简化处理以后贴出来的,导致了符号的一致性问题,不好意思。不过基本函数的调用过程是没问题,我已经更正过来了。

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP