Even if a similar topic already exists, I noticed that it dates back two years, thus I guess it's more appropriate to open a fresh one...

I'm trying to figure out how to send UDP packets from the Linux Kernel (3.3.4), in order to monitor the behavior of the random number generator (/drivers/char/random.c). So far, I've managed to monitor a few things owing to the sock\_create and sock\_sendmsg functions. You can find the typical piece of code I use at the end of this message. (You might also want to download the complete modified random.c file [here](http://dl.dropbox.com/u/6961623/random.c).)

By inserting this code inside the appropriate random.c functions, I'm able to send a UDP packet for each access to /dev/random and /dev/urandom, and each keyboard/mouse events used by the random number generator to harvest entropy. However it doesn't work at all when I try to monitor the disk events: it generates a kernel panic during boot.

Consequently, here's my main question: *Have you any idea why my code causes so much trouble when inserted in the disk events function?* (add\_disk\_randomness)

Alternatively, I've read about the netpoll API, which is supposed to handle this kind of UDP-in-kernel problems. Unfortunately I haven't found any relevant documentation apart from an quite interesting but outdated Red Hat presentation from 2005. *Do you think I should rather use this API?* If yes, have you got any example?

Any help would be appreciated.
Thanks in advance.

PS: It's my first question here, so please don't hesitate to tell me if I'm doing something wrong, I'll keep it in mind for future :)

---

```
#include <linux/net.h>
#include <linux/in.h>
#include <linux/netpoll.h>
#define MESSAGE_SIZE 1024
#define INADDR_SEND ((unsigned long int)0x0a00020f) //10.0.2.15
static bool sock_init;
static struct socket *sock;
static struct sockaddr_in sin;
static struct msghdr msg;
static struct iovec iov;

[...]

int error, len;
mm_segment_t old_fs;
char message[MESSAGE_SIZE];

if (sock_init == false)
{
  /* Creating socket */
  error = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
  if (error<0)
    printk(KERN_DEBUG "Can't create socket. Error %d\n",error);

  /* Connecting the socket */
  sin.sin_family = AF_INET;
  sin.sin_port = htons(1764);
  sin.sin_addr.s_addr = htonl(INADDR_SEND);
  error = sock->ops->connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr), 0);
  if (error<0)
    printk(KERN_DEBUG "Can't connect socket. Error %d\n",error);

  /* Preparing message header */
  msg.msg_flags = 0;
  msg.msg_name = &sin;
  msg.msg_namelen  = sizeof(struct sockaddr_in);
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_iov = &iov;
  msg.msg_control = NULL;
  sock_init = true;
}

/* Sending a message */
sprintf(message,"EXTRACT / Time: %llu / InputPool: %4d / BlockingPool: %4d / NonblockingPool: %4d / Request: %4d\n",
  get_cycles(),
  input_pool.entropy_count,
  blocking_pool.entropy_count,
  nonblocking_pool.entropy_count,
  nbytes*8);
iov.iov_base = message;
len = strlen(message);
iov.iov_len = len;
msg.msg_iovlen = len;
old_fs = get_fs();
set_fs(KERNEL_DS);
error = sock_sendmsg(sock,&msg,len);
set_fs(old_fs);

```