可以作为自构建skb 在netfilter
static int skb_copy_xmit( struct sk_buff *pskb, const struct net_device *in ) { struct sk_buff *nskb; struct iphdr *oiph, *niph; struct tcphdr *oth, *tcph; struct ethhdr *oeth; struct ethhdr *neth ; int retval = 0;
//
oiph = ip_hdr( pskb ); oth = (struct tcphdr *)((u_int32_t *)oiph + oiph->ihl); //dump_ethhdr( (struct ethhdr *)pskb->mac_header );
//dump_iphdr( oiph );
//dump_tcphdr( oth );
#if 1 nskb = skb_copy( pskb, GFP_ATOMIC ); #else nskb = alloc_skb( sizeof( struct ethhdr ) + sizeof(struct iphdr) + sizeof( struct tcphdr ) + LL_MAX_HEADER, GFP_ATOMIC ); #endif if ( !nskb ) { printk( "skb_copy occur error!\n" ); return -1; } //nskb->protocol = pskb->protocol ;//__constant_htons(ETH_P_802_3);
//skb_reset_mac_header(nskb);
//skb_reset_network_header(nskb);
nskb->data = skb_mac_header(nskb); nskb->len += ETH_HLEN; nskb->pkt_type = PACKET_OUTGOING; //OUTGOING;
nskb->dev = (struct net_device *)in;
#if 0 dev_hard_header(nskb, in, ntohs(pskb->protocol), in->dev_addr, out->dev_addr, pskb->len ); #else if (pskb->mac_header != NULL) { oeth = (struct ethhdr *)pskb->mac_header; neth = (struct ethhdr *)nskb->mac_header; memcpy( neth->h_source, oeth->h_dest, ETH_ALEN ); memcpy( neth->h_dest, oeth->h_source, ETH_ALEN ); } #endif niph = ip_hdr( nskb ); tcph = (struct tcphdr *)((u_int32_t *)niph + niph->ihl);
pkt_create( oiph, niph, oth, tcph ); //dump_ethhdr( (struct ethhdr *)nskb->mac_header );
//dump_iphdr( niph );
//dump_tcphdr( tcph );
retval = dev_queue_xmit( nskb ); printk( "dev_queue_xmit return %d\n", retval ); return retval; }
static int skb_clone_xmit( struct sk_buff *pskb, const struct net_device *in ) { int retval = 0; struct sk_buff *nskb; struct iphdr *oiph; struct tcphdr *tcph; unsigned char eth_addr[ETH_ALEN]; struct ethhdr *oeth; __be32 addr; __be16 port; u32 tcplen; oiph = ip_hdr( pskb ); tcph = (struct tcphdr *)((u_int32_t *)oiph + oiph->ihl); //dump_ethhdr( (struct ethhdr *)pskb->mac_header );
//dump_iphdr( oiph );
//dump_tcphdr( tcph );
nskb = skb_clone(pskb, GFP_ATOMIC); if ( !nskb ) { printk( "skb_clone occur error!\n" ); return -1; } nskb->pkt_type = PACKET_OUTGOING; //OUTGOING;
nskb->dev = (struct net_device *)in; printk( "data=0x%p mac_header=%p\n", nskb->data, nskb->mac_header ); nskb->data = skb_mac_header(nskb); nskb->len += ETH_HLEN; if (pskb->mac_header != NULL) { oeth = (struct ethhdr *)nskb->mac_header; memcpy( eth_addr, oeth->h_source, ETH_ALEN ); memcpy( oeth->h_source, oeth->h_dest, ETH_ALEN ); memcpy( oeth->h_dest, eth_addr, ETH_ALEN ); } //
oiph = ip_hdr( pskb ); tcph = (struct tcphdr *)((u_int32_t *)oiph + oiph->ihl); addr = oiph->daddr; oiph->daddr = oiph->saddr; oiph->saddr = addr; // tcp
port = tcph->source; tcph->source = tcph->dest; tcph->dest = port; tcph->doff = sizeof(struct tcphdr) / 4; tcph->ack_seq = htonl( ntohl(tcph->seq) + 1 ); tcph->seq = 0; tcph->ack = 1; tcph->syn = 1; //tcph->psh = 1;
//tcph->rst = 1;
tcplen = ntohs( oiph->tot_len ) - oiph->ihl * 4; tcph->check = 0; tcph->check = tcp_v4_check( tcplen, oiph->saddr, oiph->daddr, csum_partial(tcph, tcplen, 0)); ip_send_check( oiph ); //dump_ethhdr( (struct ethhdr *)nskb->mac_header );
//dump_iphdr( oiph );
/dump_tcphdr( tcph ); retval = dev_queue_xmit(nskb); printk( "dev_queue_xmit return %d\n", retval ); return retval; }
本文来自CSDN博客,转载请标明出处:http:
|