- 论坛徽章:
- 0
|
贴一下能对目标IP进行修改的模块,介绍能对目标IP进行重定位,如本来访问的是baidu.com,通过这么一定位就能自动跳转到google.com,如果放在FORWART链上,那么能对所用通过此机NAT的机器进行IP跳转,比较好玩;但我这边试有点问题,貌似不能正常建立三次握手。。大家贴一下测试结果。。。。
附代码:
#define _KERNEL_
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/config.h>
#include <linux/ip.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#define ALERT(fmt,args...) printk("Test: " fmt,##args)
#define REALIP "10.1.100.20" /* port that appears on the wire */
#define FAKEIP "10.1.100.21" /* port that appears on the wire */
static struct nf_hook_ops nfho_in;
static struct nf_hook_ops nfho_out;
//static unsigned char *drop_ip ="\x2a\xd7\xf1\x1";
__u32 in_aton(const char *);
unsigned long int magic_ip;
char *ip;
//MODULE_PARM(ip, "s");
static unsigned int my_call_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 *sk = *skb;
struct iphdr *iph = (*skb)->nh.iph;
struct tcphdr *th = (struct tcphdr*)((int *)iph+iph->ihl);
unsigned short size;
int doff = 0;
int csum = 0;
if ( iph->daddr == in_aton(FAKEIP) && iph->protocol == IPPROTO_TCP ) {
printk("test IP packet with packet to %d.%d.%d.%d \n",NIPQUAD(iph->daddr));
iph->daddr = in_aton(REALIP);
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
size = ntohs(iph->tot_len) - (iph->ihl * 4);
doff = th->doff << 2;
sk->csum = 0;
csum = csum_partial( sk->h.raw + doff, size - doff, 0 );
sk->csum = csum;
th->check = 0;
th->check = csum_tcpudp_magic(
iph->saddr,
iph->daddr,
size,
iph->protocol,
csum_partial(sk->h.raw, doff, sk->csum)
);
}
return NF_ACCEPT;
}
static unsigned int my_call_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 *sk = *skb;
struct iphdr *iph = (*skb)->nh.iph;
struct tcphdr *th = (struct tcphdr*)((int *)iph+iph->ihl);
unsigned short size;
int doff = 0;
int csum = 0;
if ( iph->saddr == in_aton(REALIP) && iph->protocol == IPPROTO_TCP ) {
printk("test IP packet with packet from %d.%d.%d.%d \n",NIPQUAD(iph->daddr));
iph->saddr = in_aton(FAKEIP);
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
size = ntohs(iph->tot_len) - (iph->ihl * 4);
doff = th->doff << 2;
sk->csum = 0;
csum = csum_partial( sk->h.raw + doff, size - doff, 0 );
sk->csum = csum;
th->check = 0;
th->check = csum_tcpudp_magic(
iph->saddr,
iph->daddr,
size,
iph->protocol,
csum_partial(sk->h.raw, doff, sk->csum)
);
}
return NF_ACCEPT;
}
__u32 in_aton(const char *str) {
unsigned long l;
unsigned int val;
int i;
l = 0;
for (i = 0; i < 4; i++) {
l <<= 8;
if (*str != '\0') {
val = 0;
while (*str != '\0' && *str != '.') {
val *= 10;
val += *str - '0';
str++;
}
l |= val;
if (*str != '\0')
str++;
}
}
return (htonl(l));
}
static int __init init(void)
{
ALERT("insmod ok!\n");
nfho_in.hook =my_call_in ;
nfho_in.hooknum = NF_IP_PRE_ROUTING; /* First for IPv4 */
nfho_in.pf = PF_INET;
nfho_in.priority = NF_IP_PRI_FIRST; /* Make our func first */
nfho_out.hook =my_call_out ;
nfho_out.hooknum = NF_IP_POST_ROUTING; /* First for IPv4 */
nfho_out.pf = PF_INET;
nfho_out.priority = NF_IP_PRI_FIRST; /* Make our func first */
nf_register_hook(&nfho_in);
nf_register_hook(&nfho_out);
return 0;
}
static void __exit fini(void)
{
ALERT("rmsmod ok!\n");
nf_unregister_hook(&nfho_in);
nf_unregister_hook(&nfho_out);
}
module_init(init);
module_exit(fini); |
[ 本帖最后由 platinum 于 2007-9-25 10:18 编辑 ] |
|