写的将skb copy/clone后转发到源地址的一段代码

可以作为自构建skb xmit发送的示范!  在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;
}

你可能感兴趣的:(struct,tcp,header,null,NetWork)