- 论坛徽章:
- 0
|
最新进展:
通过修改代码,目前可以实现端口转换功能,但IP重定向还是有问题,三次握手最后一次最后发一个R复位.
为什么端口转换没问题,而IP就不行呢??然道我这样做理论上就有问题????请高手帮忙看看
代码 访问IP:192.168.255.30:8092端口自动跳转自其60011端口,我这边测试正常)
#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 "192.168.255.30" /* port that appears on the wire */
//#define REALIP "192.168.253.206" /* port that appears on the wire */
//#define FAKEIP "192.168.255.30" /* 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;
unsigned int tcphoff=sk->nh.iph->ihl*4;
struct iphdr *iph = (*skb)->nh.iph;
struct tcphdr *th = (struct tcphdr*)((void *)sk->nh.iph + tcphoff);
unsigned short size;
int csum = 0;
if ( iph->daddr == in_aton(REALIP) && iph->protocol == IPPROTO_TCP && th->dest==htons(8092)) {
printk("test IP packet with packet to %d.%d.%d.%d \n",NIPQUAD(iph->daddr));
// iph->daddr = in_aton(FAKEIP);
th->dest=htons(60011);
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
sk->csum = 0;
th->check = 0;
csum = skb_checksum( sk, tcphoff ,sk->len-tcphoff , 0 );
sk->csum = csum;
th->check = csum_tcpudp_magic(
iph->saddr,
iph->daddr,
sk->len-tcphoff,
iph->protocol,
csum
);
sk->ip_summed = CHECKSUM_UNNECESSARY;
}
// sk->ip_summed = CHECKSUM_UNNECESSARY;
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;
unsigned int tcphoff=sk->nh.iph->ihl*4;
struct iphdr *iph = (*skb)->nh.iph;
struct tcphdr *th = (struct tcphdr*)((void *)sk->nh.iph + tcphoff);
unsigned short size;
int csum = 0;
if ( iph->saddr == in_aton(REALIP) && iph->protocol == IPPROTO_TCP && th->source==htons(60011) ) {
printk("test IP packet with packet from %d.%d.%d.%d \n",NIPQUAD(iph->saddr));
// iph->saddr = in_aton(FAKEIP);
th->source=htons(8092);
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
sk->csum = 0;
th->check = 0;
csum = skb_checksum( sk, tcphoff ,sk->len-tcphoff , 0 );
sk->csum = csum;
th->check = csum_tcpudp_magic(
iph->saddr,
iph->daddr,
sk->len-tcphoff,
iph->protocol,
csum
);
sk->ip_summed = CHECKSUM_UNNECESSARY;
}
// sk->ip_summed = CHECKSUM_UNNECESSARY;
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); |
|