2016-07-14 67 views
3

嘗試爲ipv6添加多播組,但它返回錯誤。不明白問題。在IPv4中它工作正常不能添加多播組

([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} 

遺憾的是這個主題的Erlang文檔被嚴重記錄

也試圖與像ff3c addrreses:,FF32:

UPDATE 我已經研究過二郎山/ OTP 18.2源代碼,有使用功能prim_inet:is_sockopt_val(add_membership, {{65280,0,0,0,0,0,34048,9029}, {0,0,0,0,0,0,0,0}})

它總是返回false,因爲在prim_inet:type_value_2/2我們有類型ip,值{_,_,_,_,_,_,_,_},它只等待ipv4 {_,_,_,_}。 一方面我知道爲什麼不能在打開套接字時添加ipv6的成員資格,但另一方面要做的事情是打開的問題

+0

在第三個數字中,'3'意思是'Realm Local',它尚未定義,等待RFC定義它;你可能想用'2'作爲'Admin local'。此外,在第四位數字中,高位必須爲'0'(不能大於等於8),並且如果設置了R位,則必須設置「P」位,如果「P '位被置位,必須設置'T'位(數字必須爲0,1,3或7)。設置'R'位表示您正在嵌入RP地址。可能的話,你只需要設置'T'位(第四位是'1')來表示一個暫時的,而非永久的,衆所周知的地址。這意味着使用'ff21'。 –

+0

@RonMaupin謝謝你的答案:) 我會解決它。但第二個問題是,otp只期望ipv4 addr –

+0

IPv6和IPv4是兩個完全獨立的第三層協議。任何期望IPv4地址的東西都需要IPv4地址,而不是IPv6地址。我不知道你在用什麼,但你必須有一個IPv6網絡,包括IPv6多播客戶端和源代碼。 –

回答

2

它看起來不像Erlang的驅動程序已實施IPV6_ADD_MEMBERSHIP,但它確實有生支持,所以你可以自己構建它。這種方法的一個問題是,你對頭文件中通常定義的東西進行硬編碼,所以你的解決方案不會很便攜。

-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>>, 
    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. 

實例測試發件人:

echo hi | socat - UDP6-SENDTO:\"ff3c::8500:2345\":57100 

實例運行:

$ 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 

說明我的硬編碼值

  • 如何找到我在Ifindx使用接口索引描述爲here和是因爲這64位是在我的系統int的大小,它是在MREQ在我in6.h.一個int)
  • Ip6的值是從in.h中
  • Ip6am是從IPV6_ADD_MEMBERSHIP in6.h.
+0

謝謝!這就是我正在尋找的東西 –