Reputation: 324
Trying to add multicast group for ipv6, but it returns error. don't understand the problem. with ipv4 it works fine
([email protected])1> {ok, S} = gen_udp:open(3333, [binary, {active, false}, {ip, {65342,0,0,0,0,0,34048,9029}}, inet6, {multicast_loop, false}]).
{ok,#Port<0.1587>}
([email protected])4> inet:setopts(S, [{add_membership, {{65342,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}}}]).
{error,einval}
unfortunately this topic in erlang docs is badly documented
also have tried with addrreses like ff3c: , ff32:
UPDATE
i've looked into Erlang/OTP 18.2 source code, there is using function prim_inet:is_sockopt_val(add_membership, {{65280,0,0,0,0,0,34048,9029}, {0,0,0,0,0,0,0,0}})
and it always return false, because in prim_inet:type_value_2/2 we have type ip, value {_,_,_,_,_,_,_,_}
and it waits only for ipv4 {_,_,_,_}
.
on the one hand i know why can't add membership with ipv6 when open socket, but on other hand what to do is opened question
Upvotes: 2
Views: 565
Reputation: 13495
It doesn't look like Erlang's driver has implemented IPV6_ADD_MEMBERSHIP
, but it does have raw support so you could construct it yourself. A problem with this approach is that you are hard coding things usually defined in header files, so your solution wont be very portable.
-module(unssmraw).
-export([test/0]).
test() ->
Port = 57100,
Mad = <<65340:16,0:16,0:16,0:16,0:16,0:16,34048:16,9029:16>>,
Ifindx = <<3:64/native>>,
Ip6 = 41,
Ip6am = 20,
{ok, Sock} = gen_udp:open(Port, [{reuseaddr,true}, inet6, binary]),
R3 = inet:setopts(Sock, [{raw, Ip6, Ip6am, <<Mad/binary, Ifindx/binary>> }]),
io:format("ssm ok? ~w ~n", [R3]),
receive
{udp, S, A, Pr, Pk} -> io:format("watcher sees: Socket ~p Address ~p Port ~p Packet ~p ~n", [S, A, Pr, Pk]) end.
Example test sender:
echo hi | socat - UDP6-SENDTO:\"ff3c::8500:2345\":57100
Example run:
$ erl
Erlang/OTP 19 [erts-8.0.1] [source-761e467] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.0.1 (abort with ^G)
1> unssmraw:test().
ssm ok? ok
watcher sees: Socket #Port<0.453> Address {65152,0,0,0,47734,16383,65066,
19977} Port 43511 Packet <<"hi\n">>
ok
How to find the interface index used in Ifindx
:
As of OTP 22 net:if_name2index is available to call. A language neutral description is here. I used a 64-bit since that is the size of an int on my system and it is an int in mreq in my in6.h.)
Ip6
's value is from in.h
Ip6am
is IPV6_ADD_MEMBERSHIP from in6.h.Upvotes: 2