Wysyłanie pakietów UDP z jądra Linux

Nawet jeśli podobny temat już istnieje, zauważyłem, że datuje się na dwa lata, więc myślę, że bardziej odpowiednie jest otwarcie nowego ...

Próbuję dowiedzieć się, jak wysyłać pakiety UDP z jądra systemu Linux (3.3.4), aby monitorować zachowanie generatora liczb losowych (/drivers/char/random.c). Do tej pory udało mi się monitorować kilka rzeczy dzięki funkcjom sock_create i sock_sendmsg. Możesz znaleźć typowy fragment kodu, którego używam na końcu tej wiadomości. (Możesz również pobrać cały zmodyfikowany plik random.ctutaj.)

Poprzez wstawienie tego kodu do odpowiednich funkcji random.c, mogę wysłać pakiet UDP dla każdego dostępu do / dev / random i / dev / urandom, a każde zdarzenie klawiatury / myszy używane przez generator liczb losowych do entropii zbiorów . Jednak nie działa w ogóle, gdy próbuję monitorować zdarzenia na dysku: generuje panikę jądra podczas uruchamiania.

W związku z tym oto moje główne pytanie:Czy masz jakiś pomysł, dlaczego mój kod powoduje tyle kłopotów, gdy jest wstawiony do funkcji zdarzeń dysku? (add_disk_randomness)

Alternatywnie, przeczytałem o interfejsie API netpoll, który ma obsługiwać tego rodzaju problemy z UDP w jądrze. Niestety, nie znalazłem żadnej odpowiedniej dokumentacji poza interesującą, ale przestarzałą prezentacją Red Hat z 2005 roku.Czy uważasz, że powinienem raczej użyć tego API? Jeśli tak, czy masz jakiś przykład?

Każda pomoc byłaby doceniana. Z góry dziękuję.

PS: To moje pierwsze pytanie tutaj, więc proszę nie wahaj się powiedzieć mi, czy robię coś złego, będę o tym pamiętać na przyszłość :)

<code>#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);
</code>

questionAnswers(2)

yourAnswerToTheQuestion