URN Logo
UNIX Resources » Linux » China Linux Forum » Linux防火墙和代理服务器应用 » 1 » 好心人帮忙看看吧,编写一个可加载内核模块实现ip重定向
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
好心人帮忙看看吧,编写一个可加载内核模块实现ip重定向
Author: chengzhi330    Posted: 2007-12-27 11:33    Length: 4,264 byte(s)
[Original] [Print] [Top]
我想自己编写一个可加载内核模块(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="xc0xa8x84x8c";
unsigned char *de_ip="x1cx35xd7x58";//都已写为网络字节顺序
unsigned char de_mac[]="x00x0cx29x31x66x84";
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 ");
if(sb->nh.iph->daddr==*(unsigned int *)de_ip)
{
printk("======================= ");
printk("sum is %d ",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 ",sb->nh.iph->check);
}
break;
case IPPROTO_ICMP:
printk("It's a ICMP PACKET ");
break;
case IPPROTO_UDP:
printk("It's a UDP PACKET ");
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;
}
[Original] [Print] [Top]
« Previous thread
linux要怎么样设置才能机房的服务器使用上另外机房的公网IP及带宽?
Linux防火墙和代理服务器应用
1
Next thread »
巧妙利用Linux系统IP伪装防黑
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 02:58:32, cost 0.024564981460571 ms.