Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4710885
  • 博文数量: 930
  • 博客积分: 12070
  • 博客等级: 上将
  • 技术积分: 11448
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 16:57
文章分类

全部博文(930)

文章存档

2011年(60)

2010年(220)

2009年(371)

2008年(279)

分类: LINUX

2010-01-07 13:08:16

可以作为自构建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:


阅读(1352) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~