写的将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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值