找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 2034|回复: 0

[【推荐】] 写的将skb copy/clone后转发到源地址的一段代码

[复制链接]
发表于 2009-8-6 14:33:55 | 显示全部楼层 |阅读模式
可以作为自构建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;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-5-18 05:20 , Processed in 0.356129 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表