From bb52546e9a671ed0fd55d2e5274f299a853bed51 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 5 Nov 2013 15:52:56 +0100 Subject: Implement prim_inet:socknames/1,2 and prim_inet:peernames/1,2 --- erts/preloaded/ebin/prim_inet.beam | Bin 70856 -> 72632 bytes erts/preloaded/src/prim_inet.erl | 70 +++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam index b0bef84e68..5d4be0b684 100644 Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index fa621681f3..aa700c5194 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -41,8 +41,8 @@ getifaddrs/1, getiflist/1, ifget/3, ifset/3, gethostname/1]). -export([getservbyname/3, getservbyport/3]). --export([peername/1, setpeername/2]). --export([sockname/1, setsockname/2]). +-export([peername/1, setpeername/2, peernames/1, peernames/2]). +-export([sockname/1, setsockname/2, socknames/1, socknames/2]). -export([attach/1, detach/1]). -include("inet_sctp.hrl"). @@ -574,6 +574,36 @@ setpeername(S, undefined) when is_port(S) -> {error,_}=Error -> Error end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% PEERNAMES(insock()) -> {ok, [{IP, Port}, ...]} | {error, Reason} +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +peernames(S) when is_port(S) -> + peernames(S, undefined). + +peernames(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) -> + peernames(S, AssocId); +peernames(S, AssocId) + when is_port(S), is_integer(AssocId); + is_port(S), AssocId =:= undefined -> + Q = get, + Type = [[sctp_assoc_id,0]], + case type_value(Q, Type, AssocId) of + true -> + case ctl_cmd + (S, ?INET_REQ_GETPADDRS, + enc_value(Q, Type, AssocId)) of + {ok,Addrs} -> + {ok,get_addrs(Addrs)}; + Error -> + Error + end; + false -> + {error,einval} + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% SOCKNAME(insock()) -> {ok, {IP, Port}} | {error, Reason} @@ -599,6 +629,36 @@ setsockname(S, undefined) when is_port(S) -> {error,_}=Error -> Error end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% SOCKNAMES(insock()) -> {ok, [{IP, Port}, ...]} | {error, Reason} +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +socknames(S) when is_port(S) -> + socknames(S, undefined). + +socknames(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) -> + socknames(S, AssocId); +socknames(S, AssocId) + when is_port(S), is_integer(AssocId); + is_port(S), AssocId =:= undefined -> + Q = get, + Type = [[sctp_assoc_id,0]], + case type_value(Q, Type, AssocId) of + true -> + case ctl_cmd + (S, ?INET_REQ_GETLADDRS, + enc_value(Q, Type, AssocId)) of + {ok,Addrs} -> + {ok,get_addrs(Addrs)}; + Error -> + Error + end; + false -> + {error,einval} + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% SETOPT(insock(), Opt, Value) -> ok | {error, Reason} @@ -2213,6 +2273,12 @@ ip6_to_bytes({A,B,C,D,E,F,G,H}) -> [?int16(A), ?int16(B), ?int16(C), ?int16(D), ?int16(E), ?int16(F), ?int16(G), ?int16(H)]. +get_addrs([]) -> + []; +get_addrs([F,P1,P0|Addr]) -> + {IP,Addrs} = get_ip(F, Addr), + [{IP,?u16(P1, P0)}|get_addrs(Addrs)]. + get_ip(?INET_AF_INET, Addr) -> get_ip4(Addr); get_ip(?INET_AF_INET6, Addr) -> get_ip6(Addr). -- cgit v1.2.3