To send a broadcast using the BSD sockets API, you have to declare your destination is a broadcast address. This is done with the systemcall setsockopt(2).
Here's an example, voluntarily not using erlang because:
- I don't know erlang
- The issue is not related to erlang but to the BSD sockets API.
I'll illustrate with the IPv4 loopback addresses. localhost isn't merely 127.0.0.1 but currently 127.0.0.1/8 so part of the 127.0.0.0/8 net block. That means (at least on Linux currently) this does support the broadcast semantic as can be seen with:
$ 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>
So reproducing with the handy socat command that is a good tool to debug communication with applications:
$ 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
This requires to declare the destination is a broadcast:
$ 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 +++
erlang has setsockopt(2) references in its inet module documentation reference: 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()]
Sets one or more options for a socket.
{broadcast, Boolean} (UDP sockets)
Enables/disables permission to send broadcasts.
You'll have to figure out how to add this to your erlang code.