免费注册 查看新帖 |

Chinaunix

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

linux 64位下的netfilter 与 32位下的netfilter 有什么不同 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-11 13:39 |只看该作者 |倒序浏览
linux 64位下的netfilter 与 32位下的netfilter 有什么不同
在写一个基于netfilter 进行端口nat的程序。在32位的系统上可以正常使用。但在64位的系统就没法实现功能。应用环境如下
client----->server[(80端口)-----(81端口)]
在32位上可以实现client nc server 80 数据被转到81端口。即server的81端口可与和client通迅。
但在64位系统上只能实现 client 向server的81发数据包。而server81没法向client回送数据包。
程序如下:
请大家帮忙看看。



#include <linux/netfilter.h>   
#include <linux/netfilter_ipv4.h>   
#include <linux/module.h>   
#include <linux/moduleparam.h>   
#include <linux/kernel.h>   
#include <linux/inet.h>   
#include <linux/ip.h>   
#include <linux/tcp.h>   
#include <net/checksum.h>   
#include <net/tcp.h>   
#include <net/ip.h>
MODULE_LICENSE("GPL");   

static char *            markdip= "192.168.0.155";   
static unsigned short    markdport=80;
static unsigned short    markdport2=81;

module_param(markdport,ushort,S_IRUSR);
module_param(markdport2,ushort,S_IRUSR);      
module_param(markdip,charp,S_IRUSR);     
   
#define PRINT(fmt,args...) printk("Marker: " fmt, ##args)   
   
unsigned int hook_mark_packet_in(unsigned int hookunm,
                                                                                                                                        struct sk_buff **skb,   
                                                                                                                                        const struct net_device *in,
                                                                                                                                        const struct net_device *out,
                                                                                                                                        int (*okfn)(struct sk_buff *))   
{   
        struct    iphdr *iph;   
        struct    tcphdr *tcph;  
        int        datalen;  
        iph=(struct iphdr *)(*skb)->nh.iph;
        tcph=(struct tcphdr*)((__u32 *)iph+iph->ihl);         
        /*PRINT("IP: [%u.%u.%u.%u]:%U-->[%u.%u.%u.%u]",NIPQUAD(iph->saddr),NIPQUAD(iph->daddr));*/   
        if(iph->daddr == in_aton(markdip))   
        {      
                if(iph->protocol==6)   
                        {   
                        if(ntohs(tcph->dest) == markdport)   
                                {   
                                                tcph->dest = htons(markdport2);       
                                                ip_send_check(iph); /*重新计算IP包头校验和,这一步貌似并不需要,因为IP包校验和只与IP包头有关*/   
                                                datalen = (*skb)->len - iph->ihl*4;   
                                                tcph->check = 0;   
                                                        /*重新计算TCP包头校验和,这一步很需要,否则会被接收端丢弃,TCP包校验和不仅涉及包头也包括payload*/   
                                                tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr,   
                                                csum_partial((char *)tcph, datalen, 0));   
                                                PRINT("IN: [%u.%u.%u.%u]:%u-->[%u.%u.%u.%u]:%u, %u,  tcp_check:%u\n",
                                                        NIPQUAD(iph->saddr),ntohs(tcph->source),NIPQUAD(iph->daddr),ntohs(tcph->dest), ntohs(tcph->res1),ntohs(tcph->check));
                                }              
                        }   
        }
        return NF_ACCEPT;   
}  

  
unsigned int hook_mark_packet_out(unsigned int hookunm,struct sk_buff **skb,   
                const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *))   
{   
        struct    iphdr *iph;   
        struct    tcphdr *tcph;  
        int        datalen;  
        iph=(struct iphdr *)(*skb)->nh.iph;
        tcph=(struct tcphdr*)((__u32 *)iph+iph->ihl);  

                if(iph->protocol==6)   
                        {   
                        if(ntohs(tcph->source) == markdport2)   
                                {         
                                                tcph->source = htons(markdport);
                                                ip_send_check(iph); /*重新计算IP包头校验和,这一步貌似并不需要,因为IP包校验和只与IP包头有关*/   
                                                datalen = (*skb)->len - iph->ihl*4;   
                                                tcph->check = 0;   
                                                        /*重新计算TCP包头校验和,这一步很需要,否则会被接收端丢弃,TCP包校验和不仅涉及包头也包括payload*/   
                                                tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr,   
                                                csum_partial((char *)tcph, datalen, 0));   
                                }              
                        }

        return NF_ACCEPT;   
}  


static struct nf_hook_ops nfho_in;
static struct nf_hook_ops nfho_out;

static int init_marker(void)   
{

        nfho_in.hook=hook_mark_packet_in;
        nfho_in.hooknum=NF_IP_LOCAL_IN;
        nfho_in.pf=PF_INET;   
        nfho_in.priority=NF_IP_PRI_LAST;   
        nf_register_hook(&nfho_in);
         
          
        nfho_out.hook=hook_mark_packet_out;       
        nfho_out.hooknum=NF_IP_LOCAL_OUT;       
        nfho_out.pf=PF_INET;   
        nfho_out.priority=NF_IP_PRI_FIRST+6;   
        nf_register_hook(&nfho_out);
       
        return 0;   
}   

static void exit_marker(void)   
{   
        nf_unregister_hook(&nfho_in);  
        nf_unregister_hook(&nfho_out);
}
  
module_init(init_marker);   
module_exit(exit_marker);

论坛徽章:
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
2 [报告]
发表于 2011-11-11 14:05 |只看该作者
回复 1# sztanjj

unsigned int hook_mark_packet_in(unsigned int hookunm,
                                                                                                                                        struct sk_buff **skb,   
                                                                                                                                        const struct net_device *in,
                                                                                                                                        const struct net_device *out,
                                                                                                                                        int (*okfn)(struct sk_buff *))   
{   

   
LZ 的是什么版本的内核啊,hook 接口还是老大

论坛徽章:
0
3 [报告]
发表于 2011-11-11 14:14 |只看该作者
发行版本 Red Hat Enterprise Linux Server release 5.5 (Tikanga)

内核对 Linux localhost.localdomain 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

论坛徽章:
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
4 [报告]
发表于 2011-11-11 14:44 |只看该作者
回复 1# sztanjj
linux 64位下的netfilter 与 32位下的netfilter 有什么不同
在写一个基于netfilter 进行端口nat的程序。在32位的系统上可以正常使用。但在64位的系统就没法实现功能。应用环境如下
client----->server[(80端口)-----(81端口)]
在32位上可以实现client nc server 80 数据被转到81端口。即server的81端口可与和client通迅。
但在64位系统上只能实现 client 向server的81发数据包。而server81没法向client回送数据包。


你排除应用层代码bug的可能了吗?

而且你这个模块的功能可以通过REDIRECT实现啊。为什么要自己写呢?

论坛徽章:
0
5 [报告]
发表于 2011-11-11 14:48 |只看该作者
已经排除了应用层代码bug的可能性
自己写是为了学习一下netfilter编程。

论坛徽章:
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
6 [报告]
发表于 2011-11-11 15:17 |只看该作者
回复 5# sztanjj
从代码上看不出什么明显的bug,我这没有64位的系统测试。
建议抓包分析一下,看看是否确定只有来的数据包,没有回的数据包。

论坛徽章:
0
7 [报告]
发表于 2011-11-11 15:20 |只看该作者
抓包分析过。只有进的包,没有出去的包。

论坛徽章:
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
8 [报告]
发表于 2011-11-11 15:32 |只看该作者
回复 5# sztanjj

多打一些调试信息吧,所有 LOCAL IN 和 LOCAL OUT 的包都经过了你的模块,为什么有的包没被转换成功,可以详细定位一下

论坛徽章:
0
9 [报告]
发表于 2011-11-11 16:06 |只看该作者
是不是64位系统下面的校验合的问题呀?

论坛徽章:
0
10 [报告]
发表于 2011-11-11 17:16 |只看该作者
??
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP