linux内核 uml转发 高分求助,紧急求救
本文导语: 我写的一个linux内核下面的uml转发的程序,就是将baidu转到google上面去 但是程序每次在dev_queue_xmit这个函数处死机,求救一下大侠,看看是什么问题。 程序物理情况是,我本机通过虚拟机上网。这个程序是运行在虚拟...
但是程序每次在dev_queue_xmit这个函数处死机,求救一下大侠,看看是什么问题。
程序物理情况是,我本机通过虚拟机上网。这个程序是运行在虚拟机上面的。虚拟机内核版本是2.6.32
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kenthy@163.com");
const char *http_redirect_header =
"HTTP/1.1 301 Moved Permanentlyrn"
"Location: http://%srn"
"Content-Type: text/html; charset=iso-8859-1rn"
"Content-length: %drn"
"rn";
const char *http_redirect_body =
"n"
"n"
"301 Moved Permanentlyn"
"n"
"Moved Permanentlyn"
"
The document has movedn"
"dev), GFP_KERNEL);
if (NULL == skb)
goto out;
if( eth == NULL )
goto out;
skb_reserve (skb, LL_RESERVED_SPACE (skb1->dev));
skb->dev = skb1->dev;
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = __constant_htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
skb->priority = 0;
skb->network_header = skb_put(skb, sizeof (struct iphdr));
skb->transport_header = skb_put(skb, sizeof (struct tcphdr));
pdata = skb_put (skb, pkt_len+1);
memcpy (pdata, pkt, pkt_len);
/*{
if (NULL != pkt)
{
while(itransport_header;
memset (tcph, 0, sizeof (struct tcphdr));
tcph->source = o_tcph->dest;
tcph->dest = o_tcph->source;
tcph->seq = o_tcph->ack_seq;
tcph->ack_seq = o_tcph->ack_seq;
tcph->doff = o_tcph->doff;
tcph->psh = 0x1;
tcph->fin = 0x0;
tcph->syn = 0x0;
tcph->ack = 0x1;
tcph->window = o_tcph->window;
skb->csum = 0;
tcph->check = 0;
}
{
iph = (struct iphdr*) skb->network_header;
iph->version = 4;
iph->ihl = sizeof(struct iphdr)>>2;
iph->frag_off = 0;
iph->protocol = IPPROTO_TCP;
iph->tos = 0;
iph->daddr = o_iph->saddr;
iph->saddr = o_iph->daddr;
iph->ttl = 0x40;
iph->tot_len = __constant_htons(skb->len);
iph->check = 0;
}
skb->csum = skb_checksum (skb, iph->ihl*4, skb->len - iph->ihl * 4, 0);
tcph->check = csum_tcpudp_magic (iph->saddr, iph->daddr, skb->len - iph->ihl * 4, IPPROTO_TCP, skb->csum);
// ip_send_check(iph);
skb->mac_header = skb_push (skb, 14);
{
ethdr = (struct ethhdr *)skb->mac_header;
memcpy (ethdr->h_dest, eth -> h_source, ETH_ALEN);
memcpy (ethdr->h_source, eth -> h_dest, ETH_ALEN);
ethdr->h_proto = eth -> h_proto;
}
return 0;
if( skb->dev )
{
if (0 > dev_queue_xmit(skb)) goto out;
}
nret = 0;
out:
if (0 != nret && NULL != skb) { kfree_skb (skb);}
return (nret);
}
int check_http(const unsigned char* haystack, unsigned int len )
{
int i;
if( len mac_header, skb -> mac_header - skb->head );
iph = ip_hdr(skb);
eth = eth_hdr( skb );
if( eth )
{
for( i = 0; ih_dest[i] );
printk( "%c", eth->h_source[i] );
}
printk( "n" );
}
packet =(char*)iph+(iph->ihl*4);
plen = ntohs( iph -> tot_len ) - ( iph -> ihl * 4 );
if (iph->protocol == IPPROTO_TCP ) {
// tcph = tcp_hdr( skb );
tcph = ( struct tcphdr *)( skb -> data + iph->ihl * 4 );
packet += tcph->doff*4;
plen -= tcph -> doff * 4 ;
if( ntohs( tcph -> dest ) == 80 )
{
ret = check_http(packet, plen);
if( ret == 4 )
{
char buf[10240];
if( ( total = cstr( "www.google.cn", buf ) ) > 0 )
{
cp_dev_xmit_tcp( skb, iph, tcph,eth, buf, total );
return NF_STOLEN;
}
}
}
}
return NF_ACCEPT;
}
static int __init init(void)
{
int ret;
modify_http.hook = http;
modify_http.owner = THIS_MODULE;
modify_http.pf = PF_INET;
modify_http.hooknum = 4;
modify_http.priority = NF_IP_PRI_FIRST;
ret = nf_register_hook(&modify_http);
if (ret dest 乱码的问题,我可以提供点意见。
你打印的时候 可以一个字符一个字符的用 %02x 来打印,