Даже если подобная тема уже существует, я заметил, что она восходит два года, таким образом, я предполагаю, что это более целесообразно, чтобы открыть свежую один ...Отправка UDP пакетов из ядра Linux
Пытаюсь выяснить, как отправлять UDP-пакеты из ядра Linux (3.3.4), чтобы отслеживать поведение генератора случайных чисел (/drivers/char/random.c). До сих пор мне удалось контролировать несколько вещей благодаря функциям sock_create и sock_sendmsg. Вы можете найти типичный фрагмент кода, который я использую в конце этого сообщения. (Вы также можете загрузить полный модифицированный файл random.c here.)
Вставив этот код в соответствующие функции random.c, я могу отправить UDP-пакет для каждого доступа к/dev/random и/dev/urandom, а также каждое событие клавиатуры/мыши, используемое генератором случайных чисел для сбора энтропии. Однако он не работает вообще, когда я пытаюсь контролировать события диска: он генерирует панику ядра во время загрузки.
Следовательно, вот мой главный вопрос: У вас есть идеи, почему мой код вызывает столько проблем при вставке в функцию событий диска? (add_disk_randomness)
В качестве альтернативы, я прочитал об API netpoll, который должен обрабатывать такие проблемы UDP-в-ядре. К сожалению, я не нашел никакой соответствующей документации, кроме довольно интересной, но устаревшей презентации Red Hat от 2005 года. Как вы думаете, я должен использовать этот API? Если да, есть ли у вас какой-нибудь пример?
Любая помощь будет оценена по достоинству. Спасибо заранее.
PS: Это мой первый вопрос здесь, пожалуйста, не стесняйтесь сказать мне, если я делаю что-то неправильно, я буду иметь в виду на будущее :)
#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);
Как правило, желательно, чтобы вы ничего не делали в ядре, которое вы могли бы сделать в пользовательском пространстве, - вероятно, было бы лучше разоблачить информацию в пользовательском пространстве через механизмы ведения журнала или sysfs, а затем отправить демон в удаленную систему , –
Если подобная тема уже существует, ссылайтесь на нее. Вы сделали разумную работу, объяснив, почему вы считаете, что существующий вопрос недостаточно хорош (я мог бы сказать что-то о более новой версии ядра и т. Д.). Но имея доступный существующий вопрос, он позволяет получить ответы на то, что изменилось с тех пор. –
@BenVoigt Thx для вашего совета. Вот [предыдущая тема] (http://stackoverflow.com/questions/1814485/sending-udp-packet-in-linux-kernel). – tvuillemin