|
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
MODULE_LICENSE("GPL");
static struct nf_hook_ops nfho;
struct saddr{
__u32 sip;
int n;
};
struct psd_jg {
__u32 saddr;
__u32 daddr;
unsigned char mbz;
unsigned char ptcl;
unsigned short tcpl;
};
static struct saddr gj[100];
static char SendBuf[128]={0};
static struct psd_jg psd_header;
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 char *)buffer;
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(unsigned short)(~cksum);
}
static void ip_rewrite(struct sk_buff *skb)
{
struct iphdr *iph =skb->nh.iph;
struct tcphdr *tcph=(struct tcphdr*)((__u32 *)iph+iph->ihl);
//tcph->dest=2000;
u32 odaddr = iph->saddr;
u32 osaddr = iph->daddr;
iph->daddr = odaddr;
iph->saddr = osaddr;
psd_header.saddr=iph->saddr;
psd_header.daddr=iph->daddr;
psd_header.mbz=0;
psd_header.ptcl=6;
psd_header.tcpl=sizeof(struct tcphdr);
printk("tcph->check=%u ",tcph->check); //这是系统计算的
tcph->check=0;
memcpy(SendBuf,&psd_header,sizeof(struct psd_jg));
memcpy(SendBuf+sizeof(struct psd_jg),tcph,sizeof(struct tcphdr));
tcph->check=checksum((unsigned short*)SendBuf,sizeof(struct psd_jg)+sizeof(struct tcphdr));
printk("tcph->check=%u\n",tcph->check); //这是自己计算的,为什么不对呢??
skb->pkt_type = PACKET_OUTGOING;
if(skb->dev->type==ARPHRD_ETHER)
{
unsigned char t_hwaddr[ETH_ALEN];
skb->data=(unsigned char *)skb->mac.ethernet;
skb->len+=ETH_HLEN;
memcpy(t_hwaddr,(skb->mac.ethernet->h_dest),ETH_ALEN);
memcpy((skb->mac.ethernet->h_dest),(skb->mac.ethernet->h_source),ETH_ALEN);
memcpy((skb->mac.ethernet->h_source),t_hwaddr,ETH_ALEN);
dev_queue_xmit(skb);
}
}
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 iphdr *iph;
struct tcphdr *tcph;
int i;
iph=(*skb)->nh.iph;
if(iph->protocol==6)
{
tcph=(struct tcphdr*)((__u32 *)iph+iph->ihl);
if(tcph->rst&&(tcph->dest==2000))
{
for(i=0;i<100;i++)
{
if(gj.n==0)
{
gj.sip=iph->saddr;
gj.n=1;
return NF_ACCEPT;
}
}
}
if(tcph->syn)
{
for(i=0;i<100;i++)
{
if(iph->saddr==gj.sip)
{
gj.n=0;
return NF_ACCEPT;
}
}
ip_rewrite(*skb);
return NF_STOLEN;
}
return NF_ACCEPT;
}
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;
}
void cleanup_module()
{
nf_unregister_hook(&nfho);
}
高手们快点帮一下呀,一星期没搞定!!!
系统计算的是对的,能正常发出,我自己做TCP校验就不对,不知是哪儿错了。 |
|