-module(bucinet). -export([ to_ip/1, ip_to_string/1, ip_to_binary/1, active_ip/0, active_ips/0, loopback/0, is_ip/1 ]). % @doc % Return a inet:ip4_address() from a string or a binary. % @end -spec to_ip(binary() | string()) -> inet:ip4_address() | error. to_ip(IP) when is_binary(IP) -> to_ip(bucs:to_list(IP)); to_ip(IP) when is_list(IP) -> try case [bucs:to_integer(X) || X <- string:tokens(IP, ".")] of [A, B, C, D] when A >= 0, A =< 255, B >= 0, B =< 255, C >= 0, C =< 255, D >= 0, D =< 255 -> {A, B, C, D}; _ -> error end catch _:_ -> error end; to_ip({_, _, _, _} = IP) -> IP; to_ip(_) -> error. % @doc % Return a string for the given inet:ip4_address() % @end -spec ip_to_string(inet:ip4_address()) -> string() | error. ip_to_string({A, B, C, D}) when A >= 0, A =< 255, B >= 0, B =< 255, C >= 0, C =< 255, D >= 0, D =< 255 -> lists:flatten(io_lib:format("~B.~B.~B.~B", [A, B, C, D])); ip_to_string(IP) when is_list(IP) -> case is_ip(IP) of true -> IP; false -> error end; ip_to_string(_) -> error. % @doc % Return a binary for a given inet:ip4_address() % @end -spec ip_to_binary(inet:ip4_address()) -> binary() | error. ip_to_binary(IP) when is_binary(IP) -> IP; ip_to_binary(IP) -> case ip_to_string(IP) of error -> error; Str -> bucs:to_binary(Str) end. % @doc % Return the first active IP (or loopback if none). % @end -spec active_ip() -> inet:ip4_address(). active_ip() -> case get_active_ips(get_iflist()) of [] -> loopback(); [Ip|_] -> Ip end. % @doc % Return all actives IPs. % @end -spec active_ips() -> [inet:ip4_address()]. active_ips() -> get_active_ips(get_iflist()). % @doc % Return the loopback IP. % @end -spec loopback() -> inet:ip4_address(). loopback() -> case get_loopback(get_iflist()) of [] -> error; [L|_] -> L end. % @doc % Return true if the given parameter is an IP. % @end -spec is_ip(term()) -> true | false. is_ip({A, B, C, D}) when A >= 0, A =< 255, B >= 0, B =< 255, C >= 0, C =< 255, D >= 0, D =< 255 -> true; is_ip(IP) -> error =/= to_ip(IP). % privates get_active_ips(If_list) -> get_ips([A || A <- If_list, inet:ifget(A, [addr]) /= {ok, [{addr, {127, 0, 0, 1}}]}, filter_networkcard(list_to_binary(A))]). get_iflist() -> {ok, IfList} = inet:getiflist(), IfList. filter_networkcard(<<"vboxnet", _R/binary>>) -> false; filter_networkcard(<<"vnic", _R/binary>>) -> false; filter_networkcard(<<"vmnet", _R/binary>>) -> false; filter_networkcard(<<"docker", _R/binary>>) -> false; filter_networkcard(_) -> true. get_ips(A) -> get_ips(A, []). get_ips([], R) -> R; get_ips([If|Rest], R) -> case inet:ifget(If, [addr]) of {ok, []} -> get_ips(Rest, R); {_, [{_, Ip}]} -> get_ips(Rest, [Ip|R]) end. get_loopback(If_list) -> get_ips([A || A <- If_list, inet:ifget(A, [addr]) == {ok, [{addr, {127, 0, 0, 1}}]}]).