即使类似的主题已经存在,我注意到它可以追溯到两年前,因此我想开一个新的主题更合适......
我试图弄清楚如何从 Linux 内核(3.3.4)发送 UDP 数据包,以便监视随机数生成器(/drivers/char/random.c)的行为。到目前为止,我已经通过 sock_create 和 sock_sendmsg 函数成功监控了一些事情。您可以在本消息末尾找到我使用的典型代码段。 (您可能还想下载完整修改后的 random.c 文件here http://dl.dropbox.com/u/6961623/random.c.)
通过将此代码插入适当的 random.c 函数中,我能够为每次访问 /dev/random 和 /dev/urandom 发送一个 UDP 数据包,以及随机数生成器使用的每个键盘/鼠标事件来收集熵。然而,当我尝试监视磁盘事件时,它根本不起作用:它在启动期间生成内核恐慌。
因此,这是我的主要问题:您知道为什么我的代码在插入磁盘事件函数时会造成如此多的麻烦吗?(添加磁盘随机性)
或者,我读过有关 netpoll API 的内容,它应该可以处理这种内核中的 UDP 问题。不幸的是,除了 2005 年的一个非常有趣但过时的 Red Hat 演示之外,我没有找到任何相关文档。你认为我应该使用这个 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);