【发布时间】:2010-09-25 16:38:56
【问题描述】:
我正在开发一个实验性的 Linux 内核模块,所以...
如何从 Linux 内核 UDP 广播?
【问题讨论】:
标签: linux networking module kernel
我正在开发一个实验性的 Linux 内核模块,所以...
如何从 Linux 内核 UDP 广播?
【问题讨论】:
标签: linux networking module kernel
嗯,我希望我有更多的时间来帮助你。
要让 UDP 多播工作,它必须被嵌入到您的内核中。您必须在配置内核时启用它。谷歌应该有更多信息;我希望这能让你走上正轨。
【讨论】:
-13 是-EACCES。你有 SO_BROADCAST 设置吗?如果未设置 SO_BROADCAST 并且您正在发送到广播地址,我相信 sock_sendmsg 会返回 -EACCES。
您正在寻找
您正在开发什么内核版本?我想简要浏览一下内核源代码。我没有看到 -ENOPKG 可以如何从 sock_set 返回,但我确实看到 -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
祝你好运——我希望我能为你解决这个问题。
【讨论】:
@adjuster..
实际上,我刚刚得到它。当我设置 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 man page 得到这个...
ENOPROTOOPT
该选项在指示的级别上是未知的。
...所以,我认为 SOL_SOCKET 不是传递的正确值。我也尝试过IPPROTO_UDP 而不是SOL_SOCKET,但没有成功。
编辑:http://docs.hp.com/en/32650-90372/ch02s10.html 说SO_BROADCAST 是SOL_SOCKET 级别的一个选项,但我继续得到-92
编辑:我很绝望,所以我试过SOL_UDP,还是-92。
是的,这很有趣:) ...良好的协同作用!最后(我希望我们能尽快到达那里)让我们组装一个干净而漂亮的明确答案! :)
编辑:即使硬设置广播标志,sock_sendmsg 也会失败(-13,“权限被拒绝”)
sock->sk->sk_flags |= SO_BROADCAST;
我真的需要一些帮助..
【讨论】:
查看 Linux 内核中的 IPVS(linux 虚拟服务器)代码。它已经有一个有效的 UDP 多播实现,用于共享连接状态以进行故障转移。
已经看过这个并且知道一些人已经这样做了,我真的建议创建一个 netfilter 链接并使用用户空间守护程序通过网络广播信息。
【讨论】:
以下对我有用(所以最后这个线程可以关闭)。
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,里面有广播地址。
【讨论】: