Raspbian - 广播消息时权限被拒绝

Raspbian - 广播消息时权限被拒绝

我正在 raspbian 上使用 Elixir/Erlang 包来尝试构建一个简单的 UDP 发送/接收应用程序。作为信息,我正在使用本教程

当我尝试将 UDP 数据包发送到接口指定的广播 IP 地址上的网络时eth0,我收到一条“权限被拒绝”消息。

难道真的不允许从linux向网络广播UDP消息吗?如果是这样,如何授予特定包广播消息的权限?我已经使用 IP 地址 127.0.0.1 对其进行了测试localhost,没有收到任何错误。

答案1

要使用 BSD 套接字 API 发送广播,您必须声明您的目的地是广播地址。这是通过系统调用完成的setsockopt(2)

这是一个例子,自愿不使用二郎因为:

  • 我不知道二郎
  • 该问题与 erlang 无关,而是与 BSD 套接字 API 相关。

我将用 IPv4 来说明环回地址。本地主机不仅仅是 127.0.0.1,而且目前是 127.0.0.1/8,因此是 127.0.0.0/8 网络块的一部分。这意味着(至少在目前的 Linux 上)这确实支持广播语义,如下所示:

$ ip route get 127.255.255.255
broadcast 127.255.255.255 dev lo table local src 127.0.0.1 uid 1000 
    cache <local,brd> 

所以用方便的方式复制socat命令是调试与应用程序通信的好工具:

$ echo test | socat udp4-datagram:127.255.255.255:5555 -
2021/07/04 08:40:06 socat[327412] E sendto(5, 0x55976a7a1000, 5, 0, AF=2 127.255.255.255:5555, 16): Permission denied

这需要声明目的地是广播:

$ echo test | socat udp4-datagram:127.255.255.255:5555,broadcast -
$ echo $?
0

$ echo test | strace -e trace=socket,setsockopt,sendto -- socat udp4-datagram:127.255.255.255:5555,broadcast -
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) = 5
setsockopt(5, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
sendto(5, "test\n", 5, 0, {sa_family=AF_INET, sin_port=htons(5555), sin_addr=inet_addr("127.255.255.255")}, 16) = 5
+++ exited with 0 +++

二郎setsockopt(2)其参考文献中有内网模块文档参考:socket_setopt().

socket_setopt() =
    gen_sctp:option() | gen_tcp:option() | gen_udp:option()
setopts(Socket, Options) -> ok | {error, posix()}
  
Types
Socket = socket()
Options = [socket_setopt()]

为套接字设置一个或多个选项。

{broadcast, Boolean} (UDP sockets)

启用/禁用发送广播的权限。

您必须弄清楚如何将其添加到您的二郎代码。

相关内容