I have written a driver which sends a ping packet, but it's not working (I checked using tcpdump -i wlan0 icmp
).
Basically, I have used ioctl call from a user program to start the transmission (it's working), but there is a problem in the module code.
Transmission code:
case WLAN_TRANSMIT:
icmp.type = ICMP_ECHO;
icmp.code = 0;
icmp.un.echo.sequence = i++;
icmp.un.echo.id = current -> pid & 0xFFFF;
printk(KERN_ALERT "ID::%X\n", icmp.un.echo.id);
ip4.protocol = 0x01; //for icmp protocol
ip4.tos = 0x00;
ip4.frag_off = 0;
ip4.daddr = in_aton(procfs_buffer);
ip4.saddr = in_aton(ifr -> ifr_addr.sa_data);
len = sizeof(data);
skb = dev_alloc_skb(1500);
skb -> dev = __dev_get_by_name( & init_net, "wlan0");
skb_reserve(skb, NET_IP_ALIGN); //header of 2 bytes; increments tail and data pointer
skb -> data = skb_put(skb, sizeof(len)); // increments all pointer or adds data
memcpy(data, skb -> data, len);
wdev = skb -> dev;
skb -> transport_header = skb_push(skb, sizeof(icmp));
memset(skb -> transport_header, 0, sizeof(struct icmphdr));
memcpy(skb -> transport_header, & icmp, sizeof(struct icmphdr));
skb -> network_header = skb_push(skb, sizeof(ip4));
memset(skb -> network_header, 0, sizeof(struct iphdr));
memcpy(skb -> network_header, & ip4, sizeof(struct iphdr));
// printk("i::%d\n",i);
// skb->mac_header = skb_push(skb,6*sizeof(0xFF));
//skb->mac_header = ()
skb -> mac_header = skb -> dev -> dev_addr;
if (dev_queue_xmit(skb) == NET_XMIT_SUCCESS)
printk(KERN_ALERT "success");
I am using dev_queue_xmit.
skb->mac_header = skb->dev->dev_addr
looks wrong.
The MAC header must be copied into the packet, before the IP header, and skb->data
must point to it. Setting skb->mac_header
in this context is quite meaningless.
I also don't see that you calculate the IP and ICMP checksums (the ICMP checksum is, I think, optional, but the IP checksum is mandatory).
I really can't tell if it's all.
You should see what's the return value from dev_queue_xmit
, and also print the packet contents, from skb->data
to skb->tail
and see they're a valid ICMP packet.