Sending a UDP packet within a kernel module

2019-02-28 05:41发布

Background: I'm a fourth year computer engineering major at UCSB. I've taken networking and operating systems courses. I created a program in userspace that broadcasts UDP packets onto the subnet and receives UDP packets in an adhoc network. What I'm trying to accomplish is to convert this program into a kernel module that will work on an ARM embedded system with Angstrom Linux, kernel version 2.6.39 (the x86 to ARM architecture cross compilation is an issue for another day). The reason for this move to the kernel is to shed some of the overhead of userspace functions and to make the sending and receiving part as quick as possible.

I've never done anything like this before in any of the courses I've taken, so please tell me if anything I am saying is incorrect, useless or inefficient!

After research with Google, I've concluded the typical way is to do away with sockets entirely and work with the sockbuf structure and fill in the necessary headers myself. Would this have an effect on the ability to broadcast packets on the subnet? I am currently trying to follow the code here: UDP packet send with linux-kernel module without using sockets

I've figured out the reasoning behind most of the code, but the last part is what confuses me:

eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
skb_reset_mac_header(skb);
skb->protocol = eth->h_proto = htons(ETH_P_IP);
memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
memcpy(eth->h_dest, remote_mac, ETH_ALEN);

skb->dev = dev;


dev_queue_xmit(skb);
  • All of the ethernet header seems to be constructed purely out of headers defined in the kernel besides the source MAC address, is this correct? I am going to be broadcasting my packets, so what exactly should be put into the destination MAC address field?
  • More importantly, what is dev in the skb->dev = dev; line? From my investigation, it is a pointer to the device driver it is associated with. From my understanding, I would want this to point to the wireless chip device driver as I am using 802.11 to communicate. Do I have to create my own dev struct for the wireless driver? If so, there any guidance on how to accomplish this? If not, how can I access the existing device driver and use this in a kernel module?

I've tried commenting out the dev line and running the code but unsurprisingly I get a kernel panic once it executes dev_queue_xmit(skb);.

Again, I've never done anything like this before, so any advice would be helpful, even if it means changing my approach entirely! I also understand that this could be a niche of a question, but any sort of guidance is appreciated!

Thank you in advance!

1条回答
不美不萌又怎样
2楼-- · 2019-02-28 06:29

The best way is not to interfere with the protocol if you are not trying to modify one. Work on a higher (socket) layer. This API can be found in net/socket.c

This will help: (open in new browser tab/window to zoom) Linux Kernel Network Flow

查看更多
登录 后发表回答