LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 576|回复: 0

请教一个netfilter的问题!!毕业设计!!急!!谢谢各位大哥了!!

[复制链接]
发表于 2009-3-1 22:33:50 | 显示全部楼层 |阅读模式
想实现一个拦截并可以修改http报文的程序,搭建了一个透明网桥,在netfilter里将目的IP修改成本机,用户态程序监听处理,目前netfilter那部分内核模块总是死机,同样的代码在不同的地方,一个成功一个失败,不知道什么原因

static struct nf_hook_ops nfho_in;
static struct nf_hook_ops nfho_out;

unsigned int hook_func_in(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 tcphdr *tcp_buff = NULL;
        unsigned char *http_buff = NULL;

        int tcp_len = 0;
        int http_len = 0;

/*******************************************************************************************************/       
       
        if (*((u_short *)(sb->mac.raw + 12)) != 0x0008)
                return NF_ACCEPT;
        if (sb->nh.iph->protocol != IPPROTO_TCP)
                return NF_ACCEPT;
        tcp_buff = (struct tcphdr *)(sb->data + sb->nh.iph->ihl * 4);
        if (tcp_buff->source != 0x5000 && tcp_buff->dest != 0x5000)       
                return NF_ACCEPT;

        sb = skb_copy(sb, 1);
        *skb = sb;       

        tcp_buff = (struct tcphdr *)(sb->data + sb->nh.iph->ihl * 4);
        http_buff = (unsigned char *)tcp_buff + tcp_buff->doff * 4;

/*******************************************************************************************************/
        if (tcp_buff->dest == 0x5000)       
                sb->nh.iph->daddr = 0x6f01a8c0;
/******************************************************************************************************/

        // fix sk_buff checksum                       
        tcp_len = ntohs(sb->nh.iph->tot_len) - sb->nh.iph->ihl * 4;
        http_len = tcp_len - tcp_buff->doff * 4;
        sb->csum = 0;
        sb->csum = csum_partial((unsigned char *)http_buff, http_len, 0);
        // fix tcp checksum
        tcp_buff->check = 0;
        tcp_buff->check = csum_tcpudp_magic(sb->nh.iph->saddr, sb->nh.iph->daddr, tcp_len, IPPROTO_TCP, csum_partial((unsigned char *)tcp_buff, tcp_buff->doff * 4, sb->csum));
        // fix ip checksum
        sb->nh.iph->check = 0;
        sb->nh.iph->check = ip_fast_csum((unsigned char *)sb->nh.iph, sb->nh.iph->ihl);
        return NF_ACCEPT;
}

unsigned int hook_func_out(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 tcphdr *tcp_buff = NULL;
        unsigned char *http_buff = NULL;

        int tcp_len = 0;
        int http_len = 0;

/*******************************************************************************************************/       
        printk("data out\n");
        if (*((u_short *)(sb->mac.raw + 12)) != 0x0008)
                return NF_ACCEPT;
        if (sb->nh.iph->protocol != IPPROTO_TCP)
                return NF_ACCEPT;
        tcp_buff = (struct tcphdr *)(sb->data + sb->nh.iph->ihl * 4);
        if (tcp_buff->source != 0x5000 && tcp_buff->dest != 0x5000)       
                return NF_ACCEPT;

//return NF_ACCEPT;       
// 执行到下面就死机了
        sb = skb_copy(sb, 1);
        *skb = sb;       

        tcp_buff = (struct tcphdr *)(sb->data + sb->nh.iph->ihl * 4);
        http_buff = (unsigned char *)tcp_buff + tcp_buff->doff * 4;

/*******************************************************************************************************/
        if (tcp_buff->dest == 0x5000)       
                sb->nh.iph->saddr = 0x0101a8c0;
/******************************************************************************************************/

        // fix sk_buff checksum                       
        tcp_len = ntohs(sb->nh.iph->tot_len) - sb->nh.iph->ihl * 4;
        http_len = tcp_len - tcp_buff->doff * 4;
        sb->csum = 0;
        sb->csum = csum_partial((unsigned char *)http_buff, http_len, 0);
        // fix tcp checksum
        tcp_buff->check = 0;
        tcp_buff->check = csum_tcpudp_magic(sb->nh.iph->saddr, sb->nh.iph->daddr, tcp_len, IPPROTO_TCP, csum_partial((unsigned char *)tcp_buff, tcp_buff->doff * 4, sb->csum));
        // fix ip checksum
        sb->nh.iph->check = 0;
        sb->nh.iph->check = ip_fast_csum((unsigned char *)sb->nh.iph, sb->nh.iph->ihl);
        return NF_ACCEPT;
}


int init_module()
{
        nfho_in.hook = hook_func_in;
        nfho_in.hooknum  = NF_IP_PRE_ROUTING;
        nfho_in.pf   = PF_INET;
        nfho_in.priority = NF_IP_PRI_FIRST;
       
        nfho_out.hook = hook_func_out;
        nfho_out.hooknum  = NF_IP_LOCAL_OUT;
        nfho_out.pf   = PF_INET;
        nfho_out.priority = NF_IP_PRI_FIRST;

        nf_register_hook(&nfho_in);       
        nf_register_hook(&nfho_out);

        return 0;
}

void cleanup_module()
{
        nf_unregister_hook(&nfho_in);
        nf_unregister_hook(&nfho_out);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表