3

我正在开发一个实验性的Linux 内核模块,所以......

如何从 Linux 内核进行UDP 广播?

4

5 回答 5

3

-13 是 -EACCES。你有 SO_BROADCAST 设置吗?如果未设置 SO_BROADCAST 并且您要发送到广播地址,我相信 sock_sendmsg 会返回 -EACCES 。


您正在寻找 <errno.h> 的错误代码。


你在什么内核版本下开发?我想简要浏览一下内核源代码。我没有看到如何从 sock_set 返回 -ENOPKG,但我确实看到可以返回 -ENOPROTOOPT(在内核 2.6.27 中是 errno 92)。

哦——如果你愿意的话,可以在你设置 SO_BROADCAST 的地方重新发布那段代码。我没有记下它,我想再看一遍。


尝试使用 SOL_UDP 调用它。我这就是你要找的。我在任何地方都没有 2.6.18 构建环境设置来玩这个,但试一试。

不——没关系——这不会做你想做的事。我应该在源代码中进一步阅读。我会继续寻找。这有点有趣。


我想你可以自己设置广播标志! 微笑

lock_sock(sock->sk);
sock->sk->broadcast = 1;
release_sock(sock->sk);

你把我难住了,我得去睡觉了。我确实发现了这段代码可能会有所帮助,尽管这些人没有进行广播。

http://kernelnewbies.org/Simple_UDP_Server

祝你好运——我希望我能为你解决它。

于 2008-12-06T20:26:45.737 回答
2

@调整器..

事实上,我刚刚得到它。当我设置SO_BROADCAST时,我收到 92(未安装包)

那我应该安装什么包呢?


编辑:内核版本是 2.6.18,你是对的!92 是ENOPROTOOPT

//Socket creation
sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);

//Broadcasting
int broadcast = 1;
int err;

if( (err = sock->ops->setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof broadcast)) < 0 )
{
    printk(KERN_ALERT MODULE_NAME ": Could not configure broadcast, error %d\n", err);
    return -1;
}

编辑:我从setsockopt 手册页得到了这个......

ENOPROTOOPT
该选项在指示的级别上是未知的。

...所以,我认为这SOL_SOCKET不是正确的传递值。我也尝试过IPPROTO_UDP,而不是SOL_SOCKET没有运气。


编辑: http: //docs.hp.com/en/32650-90372/ch02s10.html说这SO_BROADCASTSOL_SOCKET级别的一个选项,但我继续得到-92


编辑:我很绝望,所以我试过SOL_UDP了,还是-92。
是的,这很有趣:) ...良好的协同作用!最后(我希望我们能尽快到达那里)让我们组装一个干净而漂亮的明确答案!:)


编辑:即使硬设置广播标志,sock_sendmsg也会失败(-13,“权限被拒绝”)

sock->sk->sk_flags |= SO_BROADCAST;

我真的需要一些帮助。

于 2008-12-06T20:29:59.817 回答
1

嗯,我希望我有更多的时间来帮助你。

为了让 UDP 多播工作,它必须被嵌入到你的内核中。您必须在配置内核时启用它。谷歌应该有更多信息;我希望这能让你走上正确的道路。

于 2008-12-06T20:14:30.660 回答
0

查看 Linux 内核中的 IPVS(linux 虚拟服务器)代码。它已经有一个 UDP 多播的工作实现,它用于共享连接状态以进行故障转移。

已经看过这个并且知道一些人已经这样做了,我真的建议创建一个 netfilter 链接并使用用户空间守护程序通过网络广播信息。

于 2008-12-09T21:53:31.097 回答
0

以下对我有用(所以最后这个线程可以关闭)。

int yes = 1;
sock_setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));

sock->ops->connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr), 0);

这里sock是一个初始化的struct socket并且 addr 应该是struct sockaddr_in里面有一个广播地址。

于 2016-06-22T10:38:53.477 回答