Sending Udp Packets from the Linux Kernel

Sending UDP packets from the Linux Kernel

I solved my problem a few months ago. Here's the solution I used.

The standard packet-sending API (sock_create, connect, ...) cannot be used in a few contexts (interruptions). Using it in the wrong place leads to a KP.

The netpoll API is more "low-level" and works in every context. However, there are several conditions :

  • Ethernet devices
  • IP network
  • UDP only (no TCP)
  • Different computers for sending and receiving packets (You can't send to yourself.)

Make sure to respect them, because you won't get any error message if there's a problem. It will just silently fail :) Here's a bit of code.

Declaration

#include <linux/netpoll.h>
#define MESSAGE_SIZE 1024
#define INADDR_LOCAL ((unsigned long int)0xc0a80a54) //192.168.10.84
#define INADDR_SEND ((unsigned long int)0xc0a80a55) //192.168.10.85
static struct netpoll* np = NULL;
static struct netpoll np_t;

Initialization

np_t.name = "LRNG";
strlcpy(np_t.dev_name, "eth0", IFNAMSIZ);
np_t.local_ip = htonl(INADDR_LOCAL);
np_t.remote_ip = htonl(INADDR_SEND);
np_t.local_port = 6665;
np_t.remote_port = 6666;
memset(np_t.remote_mac, 0xff, ETH_ALEN);
netpoll_print_options(&np_t);
netpoll_setup(&np_t);
np = &np_t;

Use

char message[MESSAGE_SIZE];
sprintf(message,"%d\n",42);
int len = strlen(message);
netpoll_send_udp(np,message,len);

Hope it can help someone.

Sending a UDP packet within a kernel module

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

Sending UDP packet in Linux Kernel

You may find it easier to use the netpoll API for UDP. Take a look at netconsole for an example of how it's used. The APIs you're using are more intended for userspace (you should never have to play with segment descriptors to send network data!)

Sending small UDP packets from the Linux Kernel to LOOPBACK

Since it sometimes works and sometimes doesn't I'd suggest the problem is that you are looking at memory which has been free()d. Thus the contents are sometimes correct and sometimes they are mangled. Since your local buffer is fine this must be occurring in the kernel before it is copied to local memory.

Indeed is the unsigned char testmsg[] declared as a local variable?

Since the message isn't sent straight away the testmsg address that you pass is on the stack. If there are subsequent functional calls then they will over write the contents of the message before it is sent. Then you will sometimes see the correct message and sometimes not. Depending on the scheduling of the work.

Linux - Sending packets from inside the kernel

As I tried to find the solution by using netpoll, I found that using socket might be more useful.
I found this link of a github repository that have exactly the example of echo client server in the linux kernel.

Hope it will help everyone who searched for it too.

Path of UDP packet in linux kernel

The linux networking stack is a big piece of the kernel and you need to spend some time studying it.
I think that this books may help (Focused on older kernels 2.4 and 2.6, but the logic remain the same for the latest kernels 3.x):

Understanding Linux Network Internals

The Linux Networking Architecture - Design and Implementation of Network Protocols in the Linux Kernel

You can also checkout this links:

http://e-university.wisdomjobs.com/linux/chapter-189-277/sending-the-data-from-the-socket-through-udp-and-tcp.html

http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow

http://wiki.openwrt.org/doc/networking/praxis

http://www.ibm.com/developerworks/linux/library/l-linux-networking-stack/?ca=dgr-lnxw01lnxNetStack

http://gicl.cs.drexel.edu/people/sevy/network/Linux_network_stack_walkthrough.html

You need also to browse the kernel source :

http://lxr.linux.no/#linux+v3.7.3/

Begin your road to the network sub-system with this function :
ip_rcv which is called when a packet is received.
other functions are then called (ip_rcv_finish, ip_local_deliver and ip_local_deliver_finish=> This function is responsible for choosing the good transport layer)



Related Topics



Leave a reply



Submit