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