title: Sending UDP packets from the Linux Kernel
body: <p>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...</p>
  
  <p>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 <a href="http://dl.dropbox.com/u/6961623/random.c" rel="noreferrer">here</a>.)</p>
  
  <p>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.</p>
  
  <p>Consequently, here's my main question: <em>Have you any idea why my code causes so much trouble when inserted in the disk events function?</em> (add_disk_randomness)</p>
  
  <p>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. <em>Do you think I should rather use this API?</em> If yes, have you got any example?</p>
  
  <p>Any help would be appreciated.
  Thanks in advance.</p>
  
  <p>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 :)</p>
  
  <hr>
  
  <pre><code>#include &lt;linux/net.h&gt;
  #include &lt;linux/in.h&gt;
  #include &lt;linux/netpoll.h&gt;
  #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, &amp;sock);
    if (error&lt;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-&gt;ops-&gt;connect(sock, (struct sockaddr *)&amp;sin, sizeof(struct sockaddr), 0);
    if (error&lt;0)
      printk(KERN_DEBUG "Can't connect socket. Error %d\n",error);
  
    /* Preparing message header */
    msg.msg_flags = 0;
    msg.msg_name = &amp;sin;
    msg.msg_namelen  = sizeof(struct sockaddr_in);
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_iov = &amp;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,&amp;msg,len);
  set_fs(old_fs);
  </code></pre>