tcp:
int cp_dev_xmit_tcp (char * eth, u_char * smac, u_char * dmac,
u_char * pkt, int pkt_len,
u_long sip, u_long dip,
u_short sport, u_short dport, u_long seq, u_long ack_seq, u_char psh, u_char fin)
{
struct sk_buff * skb = NULL;
struct net_device * dev = NULL;
struct ethhdr * ethdr = NULL;
struct iphdr * iph = NULL;
struct tcphdr * tcph = NULL;
u_char * pdata = NULL;
int nret = 1;
if (NULL == smac || NULL == dmac) goto out;
dev = dev_get_by_name (&init_net, eth);
if (NULL == dev) goto out;
skb = alloc_skb (pkt_len + sizeof (struct iphdr) + sizeof (struct tcphdr) + LL_RESERVED_SPACE (dev), GFP_ATOMIC);
if (NULL == skb) goto out;
skb_reserve (skb, LL_RESERVED_SPACE (dev));
skb->dev = dev;
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = __constant_htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
skb->destructor = cup_destroy;
skb->priority = 0;
skb->network_header = skb_put (skb, sizeof (struct iphdr));
skb->transport_header = skb_put (skb, sizeof (struct tcphdr));
pdata = skb_put (skb, pkt_len);
{
if (NULL != pkt) memcpy (pdata, pkt, pkt_len);
}
{
tcph = (struct tcphdr *) skb->transport_header;
memset (tcph, 0, sizeof (struct tcphdr));
tcph->source = sport;
tcph->dest = dport;
tcph->seq = seq;
tcph->ack_seq = ack_seq;
tcph->doff = 5;
tcph->psh = psh;
tcph->fin = fin;
tcph->ack = 1;
tcph->window = __constant_htons (65535);
skb->csum = 0;
tcph->check = 0;
}
{
iph = (struct iphdr*) skb->network_header;
iph->version = 4;
iph->ihl = sizeof(struct iphdr)>>2;
iph->frag_off = 0;
iph->protocol = IPPROTO_TCP;
iph->tos = 0;
iph->daddr = dip;
iph->saddr = sip;
iph->ttl = 0x40;
iph->tot_len = __constant_htons(skb->len);
iph->check = 0;
}
skb->csum = skb_checksum (skb, iph->ihl*4, skb->len - iph->ihl * 4, 0);
tcph->check = csum_tcpudp_magic (sip, dip, skb->len - iph->ihl * 4, IPPROTO_TCP, skb->csum);
ip_send_check(iph);
skb->mac_header = skb_push (skb, 14);
{ //eth header
ethdr = (struct ethhdr *) skb->mac_header;
memcpy (ethdr->h_dest, dmac, ETH_ALEN);
memcpy (ethdr->h_source, smac, ETH_ALEN);
ethdr->h_proto = __constant_htons (ETH_P_IP);
}
print_ip ((struct iphdr *)skb->network_header);
dump_block ("before xmit", skb->data, skb->len);
if (0 > dev_queue_xmit(skb)) goto out;
MSG_DEBUG ("dev_queue_xmit succ/n");
MSG_DEBUG ("skb->len = %d/n", skb->len);
nret = 0;
out:
if (0 != nret && NULL != skb) {dev_put (dev); kfree_skb (skb);}
return (nret);
}
======================================================================================
udp:
void my_cup (void)
{
struct sk_buff * skb = NULL;
struct net_device * dev = NULL;
u_char pkt_eth [14] = {
0x00, 0x1E, 0x37, 0x82, 0x9D, 0xFF, 0x00, 0x0C,
0x29, 0xF1, 0xF9, 0x87, 0x08, 0x00 }; //eth
u_char pkt_ip [20] = {
0x45, 0x00,
0x00, 0x54, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01,
0xB6, 0x90, 0xC0, 0xA8, 0x01, 0x67, 0xC0, 0xA8,
0x01, 0x61 }; //ip
u_char pkt_icmp [8] = {
0x08, 0x00, 0x2A, 0x7D, 0x1B, 0x08, //icmp
0x00, 0x01 };
u_char pkt_data [56] = {
0x69, 0xD5, 0x43, 0x48, 0x14, 0x59,
0x06, 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37
};
MSG_DEBUG ("send /n");
dev = dev_get_by_name (&init_net, "eth2");
MSG_DEBUG ("dev name : %s/n", dev->name);
skb = alloc_skb (100, GFP_ATOMIC);
//skb = dev_alloc_skb (100);
if (NULL == skb) return;
skb->dev = dev;
skb->pkt_type = PACKET_OTHERHOST;//PACKET_OUTGOING;
skb->protocol = __constant_htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
skb->destructor = cup_destroy;
skb->priority = 0;
skb_reserve (skb, 16);
memcpy (skb_push (skb, 14), pkt_eth, 14);
skb->network_header = skb_put (skb, sizeof (struct iphdr));
memcpy (skb->network_header, pkt_ip, sizeof (struct iphdr));
skb->transport_header = skb_put (skb, sizeof (struct icmphdr));
memcpy (skb->transport_header, pkt_icmp, sizeof (struct icmphdr));
memcpy (skb_put (skb, 56), pkt_data, 56);
MSG_DEBUG ("skb->network_header = %p /n", skb->network_header);
MSG_DEBUG ("skb->data %p /n", skb->data);
MSG_DEBUG ("skb->tail %p /n", skb->tail);
skb->tail = skb->data + 98;
MSG_DEBUG ("skb->tail %p /n", skb->tail);
print_ip ((struct iphdr *)skb->network_header);
dump_block ("before xmit", skb->data, skb->len);
if (0 > dev_queue_xmit(skb)) { kfree_skb (skb); dev_put(dev); MSG_DEBUG ("dev_queue_xmit error/n"); }
else {
MSG_DEBUG ("dev_queue_xmit succ/n");
MSG_DEBUG ("skb->len = %d/n", skb->len);
}
return;
}