从 Linux 内核发送 UDP 数据包

2024-01-07

即使类似的主题已经存在,我注意到它可以追溯到两年前,因此我想开一个新的主题更合适......

我试图弄清楚如何从 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);

几个月前我解决了我的问题。这是我使用的解决方案。

标准数据包发送 API(sock_create、connect 等)无法在少数情况下(中断)使用。在错误的地方使用它会导致 KP。

netpoll API 更加“低级”,并且适用于所有上下文。但是,有几个条件:

  • 以太网设备
  • IP网络
  • 仅 UDP(无 TCP)
  • 用于发送和接收数据包的不同计算机(您不能发送给自己。)

请务必尊重它们,因为如果出现问题,您不会收到任何错误消息。它只会默默地失败:) 这是一些代码。

宣言

#include <linux/netpoll.h>
#define MESSAGE_SIZE 1024
#define INADDR_LOCAL ((unsigned long int)0xc0a80a54) //192.168.10.84
#define INADDR_SEND ((unsigned long int)0xc0a80a55) //192.168.10.85
static struct netpoll* np = NULL;
static struct netpoll np_t;

初始化

np_t.name = "LRNG";
strlcpy(np_t.dev_name, "eth0", IFNAMSIZ);
np_t.local_ip = htonl(INADDR_LOCAL);
np_t.remote_ip = htonl(INADDR_SEND);
np_t.local_port = 6665;
np_t.remote_port = 6666;
memset(np_t.remote_mac, 0xff, ETH_ALEN);
netpoll_print_options(&np_t);
netpoll_setup(&np_t);
np = &np_t;

Use

char message[MESSAGE_SIZE];
sprintf(message,"%d\n",42);
int len = strlen(message);
netpoll_send_udp(np,message,len);

希望它可以帮助别人。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Linux 内核发送 UDP 数据包 的相关文章

随机推荐

  • 在我的 Android 项目中使用领域数据库时无法生成 GlideApp 和 Glide 请求

    我使用 Glide 来处理图像 到目前为止它运行良好 但是现在 当我将 Realm 数据库集成到我的项目中时 它在生成 GlideApp 和 GlideRequests 类时出现错误 主要构建 gradle buildscript repo
  • GIF 图像在“document.location.href”时停止

    我在 javascript 中有这个函数 function loadPage url showLoadPageGif visibility On document location href getPath url 当我使用此功能时 GIF
  • 如何从 Knex / Postgresql 查询返回纯值?

    我正在尝试使用 Knex 从 Postgres DB 返回一个简单的标量字符串值 到目前为止 我所做的一切都会返回一个带有键 列名 和值的 JSON 对象 因此我必须访问该对象才能获取值 如果我返回多行 那么我会得到多个 JSON 对象 每
  • Python 动态属性和 mypy

    我试图将一些函数屏蔽为属性 通过包装器 这在这里并不重要 并将它们动态添加到对象中 但是 我需要代码完成和 mypy 才能工作 我想出了如何动态添加属性 通过元类或简单地在构造函数中 但我遇到的问题是 mypy 没有选择它 IDE 也没有
  • 如何从android将值传递到php?

    我在将值从 android 传递到 php 脚本时遇到问题 我想要questionid传递到 php 脚本url get ansurl但我无法传递该值 这个怎么做 请指导我 多谢 try int success json getInt TA
  • 自定义 UIAlertView 上的按钮

    这是我自定义按钮的当前方式 UIAlertView av UIAlertView alloc init av addButtonWithTitle UIButton yesButton av subviews lastObject av s
  • 使用 htaccess 将网站重定向到移动版网站

    您好 我使用以下代码重定向到移动网站 从移动到移动网站 移动中的domain com到m domain com 它工作正常 但网址末尾的 id 9 即将到来 如何删除 id 9 从 url 以及如何将移动网站 m domain com 从桌
  • Android 视图转换是否在光栅化后应用?

    下面代码中的行 A 和行 B 应生成相同的图像 然而 行 A 却生成了图像 怎么了 光栅化后是否应用视图 画布转换 import android content Context import android graphics Canvas
  • express.js - 单行中多个路由的单个路由处理程序

    有没有办法在单个函数调用中做到这一点 var todo function req res app get todo app get blabla todo app get blablablabla todo 就像是 app get blab
  • Google 联系 gdata (Java) 因内容类型没有解析器而失败:application-xml[application/xml]

    最近 两天前 当我们尝试访问联系人时 我们开始在 Java 中的 google gdata 客户端中遇到异常 提要 m8 feeds contacts default full 例外的是 com google gdata util Pars
  • 如何使用 Gmail Api 获取邮件列表?

    我想访问消息列表 Object 2 0 0 p481 008 gt g gmail api users messages list gt lt Google APIClient Method 0x41c948c ID gmail users
  • SQLite多进程访问

    我们在多进程和多线程应用程序中使用 SQLite SQLite 数据库文件使用嵌入式 SQLite 加密进行加密 这FAQ http sqlite org faq html q5指出 SQLite 应该能够使用锁机制来管理多进程访问 我们遇
  • WPF - 在系统帐户下执行进程时性能低下

    问题描述 我有一个 WPF 应用程序 通常在具有管理员权限的本地用户帐户下运行 但是 在某些情况下 该进程是由运行在下面的服务或脚本启动的SYSTEM帐户 因此该进程也在SYSTEM帐户 问题是当进程运行时SYSTEM帐户时 存在一些明显的
  • 编写一个程序来计算级数的项之和

    编写一个程序来计算级数项的总和 4 8 12 16 20 24 28 32 n 其中 n 是输入 考虑 n 始终有效 其中 意味着它遵循系列模式 n int input Enter n sum 0 for i in range 4 n 4
  • 如何使用新的 SVN 合并跟踪?

    在我现有的 SVN 1 5 之前 合并策略中 我们在创建分支时创建主干的副本 称为 BasePoint 以便稍后在合并过程中引用 当我们需要将分支合并回主干时 我们执行 2 个操作 从 BasePoint 合并到 LatestTrunk 主
  • mysql 与 php 计算行数的最佳实践

    1 计数记录 Connect to mysql server link mysql connect HOST USER PASSWORD if link die Could not connect to server mysql error
  • docker-compose 可以在具有离散端口的服务之间共享 IP 吗?

    目前 我们拥有使用 Supervisord 进行复杂构建的 docker 容器 以便我们可以将服务分组在一起 例如 nginx 和 ssh 我正在尝试使用由共享卷链接的更多服务驱动的隔离来重建这些 然而 无需将 IP 映射到主机 我似乎找不
  • OrientDB ETL 在加载 CSV 文件时抛出异常

    我试图将一个简单的 CSV 文件加载到 OrientDB 但它总是抛出此异常 CSV 文件内容 id name role 1 Sarath Architect 2 Anoop Project Manager 3 Nazeem Lead De
  • 第一次更新和启动应用程序时是否会调用 applicationDidFinishLaunching: ?

    Is applicationDidFinishLaunching保证在应用程序更新后调用 当用户首次启动更新版本时 换句话说 如果旧版本在更新过程中以后台模式运行 它会被杀死吗 是的 如果您的应用程序处于后台 更新程序将在升级之前终止您的应
  • 从 Linux 内核发送 UDP 数据包

    即使类似的主题已经存在 我注意到它可以追溯到两年前 因此我想开一个新的主题更合适 我试图弄清楚如何从 Linux 内核 3 3 4 发送 UDP 数据包 以便监视随机数生成器 drivers char random c 的行为 到目前为止