からUDPパケットを送信します乱数ジェネレータ(/drivers/char/random.c)の動作を監視するために、Linuxカーネル(3.3.4)からUDPパケットを送信する方法を解説します。これまでは、sock_create関数とsock_sendmsg関数のためにいくつかのことを監視してきました。このメッセージの最後に私が使用する典型的なコードを見つけることができます。 (完全修飾random.cファイルhereをダウンロードすることもできます)。は私がしようとしている...私はそれが新鮮なものを開くために、より適切だと思うので、それは2年さかのぼること</p> <p>に気づいた、類似したトピックがすでに存在する場合でも、Linuxカーネル
このコードを適切なrandom.c関数内に挿入すると、/ dev/randomへのアクセスごとにUDPパケットを送信できます/ dev/urandom、および乱数ジェネレータがエントロピーを収穫するために使用する各キーボード/マウスイベントです。しかし、ディスクイベントを監視しようとすると、まったく動作しません。起動時にカーネルパニックが発生します。
私の主な質問は次のとおりです。ディスクイベント機能にコードを挿入すると、なぜ私のコードが問題になるのですか?(add_disk_randomness)
また、この種のUDPカーネルの問題を処理するはずのnetpoll APIについても読んだことがあります。残念ながら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);
一般に、ユーザ空間で行うことができるカーネルでは何もしないことが望ましいです。ロギングメカニズムやsysfsを介してユーザ空間に情報を公開してから、リモートシステムにデーモンに送信させる方がよいでしょう。 –
類似のトピックが既に存在する場合は、そのトピックにリンクします。あなたは、既存の質問が十分ではないと思う理由を説明する合理的な仕事をしました(私は新しいカーネルバージョンなどについて何か言っているかもしれません)。しかし、既存の質問を簡単に利用できるようにすることで、その後の変化に焦点を当てることができます。 –
@BenVoigt Thxあなたの助言のために。これは、[前のトピック](http://stackoverflow.com/questions/1814485/sending-udp-packet-in-linux-kernel)です。 – tvuillemin