Отправка пакетов UDP из ядра Linux
Даже если подобная тема уже существует, я заметил, что она существует два года назад, поэтому я думаю, что более уместно открыть новую ...
Я пытаюсь выяснить, как отправлять UDP-пакеты из ядра Linux (3.3.4), чтобы отслеживать поведение генератора случайных чисел (/drivers/char/random.c). До сих пор мне удалось отследить несколько вещей благодаря функциям sock_create и sock_sendmsg. Вы можете найти типичный фрагмент кода, который я использую в конце этого сообщения. (Вы также можете скачать полный измененный файл random.cВот.)
Вставив этот код в соответствующие функции random.c, я могу отправлять UDP-пакет для каждого доступа к / dev / random и / dev / urandom и для каждого события клавиатуры / мыши, используемого генератором случайных чисел для сбора энтропии. , Однако он не работает вообще, когда я пытаюсь отслеживать дисковые события: он генерирует панику ядра во время загрузки.
Следовательно, вот мой главный вопрос:Have you any idea why my code causes so much trouble when inserted in the disk events function? (Add_disk_randomness)
В качестве альтернативы я читал об API netpoll, который должен разрешать такого рода проблемы UDP-в-ядре. К сожалению, я не нашел никакой соответствующей документации, кроме довольно интересной, но устаревшей презентации Red Hat 2005 года.Do you think I should rather use this API? Если да, есть ли у вас пример?
Любая помощь будет оценена. Заранее спасибо.
PS: Это мой первый вопрос здесь, поэтому, пожалуйста, не стесняйтесь сказать мне, если я делаю что-то не так, я буду помнить об этом на будущее :)
<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>