本版版主招募中

 
标题: [疑问] 编写netfilter下目标ip重定向的问题
chengzhi330
LU新生
Rank: 1



UID 100835
精华 0
积分 1
帖子 2
活跃指数 1
LU金币 3 个
LU金条 0 个
阅读权限 10
注册 2007-12-26
 
发表于 2007-12-27 10:56  资料  个人空间  短消息  加为好友 
编写netfilter下目标ip重定向的问题

我想自己编写一个可加载内核模块(LKM)来实现对转发的数据包进行重定向到某一个固定目标,模块中定义的钩子函数被添加到netfilter中的NF_IP_PRE_ROUTING钩子点上。为了在netfilter的NF_IP_PRE_ROUTING上对数据包重定向,此模块程序修改从局域网外发送过来的数据包的目的地址,网关有两个接口,一个接外部,一个接内部,当外部网访问网关时,修改目的地址为内网中的一个地址,但是我在作局域网服务器网关的机器上装载了该模块后,显示是无法显示网页。
我的源程序如下, 请问为什么不能实现重定向功能呢?是不是实现数据包重定向没有这么简单,或者还是需要其他的操作步骤?
(以下源程序编译已经通过:我的编译方法是:gcc -O2 -Wall -c -I/usr/src/linux-2.4.20-8/include redirection.c)?

#define __KERNEL__
#define MODULE

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4.h>


static struct nf_hook_ops nfho;
unsigned char *re_ip="\xc0\xa8\x84\x8c";
unsigned char *de_ip="\x1c\x35\xd7\x58";
//unsigned char *re_ip="\x1c\x35\xd7\x58";
unsigned char de_mac[]="\x00\x0c\x29\x31\x66\x84";
unsigned short checksum(unsigned short *buffer, int size)
{
    unsigned long cksum=0;
    while(size>1)
        {
            cksum+=*buffer++;
            size-=sizeof(unsigned short);
            
        }
       if(size) cksum+=*(unsigned short *)buffer;
       cksum=(cksum >> 16)+(cksum&0xffff);
       cksum+=(cksum >> 16);
       return (unsigned short)(~cksum);

}
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;
    unsigned char src_ip[4];
    *(unsigned int *)src_ip = sb->nh.iph->saddr;
    printk("A packet from:%d.%d.%d.%d Detected!",
                 src_ip[0],src_ip[1],src_ip[2],src_ip[3]);
    switch(sb->nh.iph->protocol)
    {
       case IPPROTO_TCP:
           printk("It's a TCP PACKET\n");
           if(sb->nh.iph->daddr==*(unsigned int *)de_ip)
           {
           printk("=======================\n");
       printk("sum is %d\n",sb->nh.iph->check);
                  
               sb->nh.iph->daddr=*(unsigned int *)re_ip;
           sb->nh.iph->check=0;
       //memcpy(sb->mac.ethernet->h_dest,de_mac,6); //是否要改目的mac地址?
         sb->nh.iph->check=checksum((unsigned short *)sb->nh.iph, sizeof(struct iphdr));
        printk("new check is %d\n",sb->nh.iph->check);
           }
           break;
       case IPPROTO_ICMP:
           printk("It's a ICMP PACKET\n");
                      break;
       case IPPROTO_UDP:
           printk("It's a UDP PACKET\n");
                     break;
    }
    return NF_ACCEPT;         
}


int init_module()
{
  
    nfho.hook = hook_func;         
    nfho.hooknum  = NF_IP_PRE_ROUTING;
    nfho.pf       = PF_INET;
    nfho.priority = NF_IP_PRI_FIRST;  

    nf_register_hook(&nfho);

    return 0;
}

顶部
 



当前时区 GMT+8, 现在时间是 2008-9-5 15:35
乐悠LoveUnix论坛-京ICP备05005823号

Thanks to Discuz!  © 2001-2007    Power by LoveUnix.net
Processed in 0.056205 second(s), 6 queries , Gzip enabled

清除 Cookies - 联系我们 - 乐悠LoveUnix - Archiver