-module(pf_route_util). -export([module/0, parse_ip_address_with_netmask/1]). -export([read_bitmask/2]). read_bitmask(List, Integer) -> read_bitmask(List, Integer, []). read_bitmask([{V, Name} | Rest], I, Acc) -> if (I band V) =:= V -> read_bitmask(Rest, I, [Name | Acc]); true -> read_bitmask(Rest, I, Acc) end; read_bitmask([], _, Acc) -> lists:reverse(Acc). module() -> case os:type() of {unix, linux} -> {ok, pf_route_linux}; {unix, darwin} -> {ok, pf_route_macos}; {unix, freebsd} -> {ok, pf_route_freebsd}; unsupported -> {error, {unsupported_platform, unsupported}} end. -spec parse_ip_address_with_netmask(string()) -> {inet:ip_address(), non_neg_integer()}. parse_ip_address_with_netmask(S) -> logger:warning("IPNets ~p", [S]), case re:split(S, "/", [{return, list}, {parts, 2}]) of [Prefix, LenStr] -> {Prefix1, Scope} = ipv6_scope(Prefix), {ok, Addr} = inet:parse_address(Prefix1), {PrefixLen, _} = string:to_integer(LenStr), {Addr, Scope, PrefixLen}; [Prefix] -> {Prefix1, Scope} = ipv6_scope(Prefix), {ok, Addr} = inet:parse_address(Prefix1), PrefixLen = case inet_cidr:is_ipv6(Addr) of true -> 128; false -> 32 end, {Addr, Scope, PrefixLen} end. ipv6_scope(Addr) -> case re:split(Addr, "%", [{return, list}, {parts, 2}]) of [IP, Scope] -> {IP, Scope}; [IP] -> {IP, undefined} end.